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_VARDECLARATIONS 9 #define SKSL_VARDECLARATIONS 10 11 #include "include/private/SkSLProgramElement.h" 12 #include "include/private/SkSLStatement.h" 13 #include "src/sksl/ir/SkSLExpression.h" 14 #include "src/sksl/ir/SkSLVariable.h" 15 16 namespace SkSL { 17 18 namespace dsl { 19 class DSLCore; 20 } 21 22 /** 23 * A single variable declaration statement. Multiple variables declared together are expanded to 24 * separate (sequential) statements. For instance, the SkSL 'int x = 2, y[3];' produces two 25 * VarDeclaration instances (wrapped in an unscoped Block). 26 */ 27 class VarDeclaration final : public Statement { 28 public: 29 inline static constexpr Kind kStatementKind = Kind::kVarDeclaration; 30 31 VarDeclaration(const Variable* var, 32 const Type* baseType, 33 int arraySize, 34 std::unique_ptr<Expression> value, 35 bool isClone = false) 36 : INHERITED(var->fLine, kStatementKind) 37 , fVar(var) 38 , fBaseType(*baseType) 39 , fArraySize(arraySize) 40 , fValue(std::move(value)) 41 , fIsClone(isClone) {} 42 ~VarDeclaration()43 ~VarDeclaration() override { 44 // Unhook this VarDeclaration from its associated Variable, since we're being deleted. 45 if (fVar && !fIsClone) { 46 fVar->detachDeadVarDeclaration(); 47 } 48 } 49 50 // Checks the modifiers, baseType, and storage for compatibility with one another and reports 51 // errors if needed. This method is implicitly called during Convert(), but is also explicitly 52 // called while processing interface block fields. 53 static void ErrorCheck(const Context& context, int line, const Modifiers& modifiers, 54 const Type* baseType, Variable::Storage storage); 55 56 // Does proper error checking and type coercion; reports errors via ErrorReporter. 57 static std::unique_ptr<Statement> Convert(const Context& context, std::unique_ptr<Variable> var, 58 std::unique_ptr<Expression> value, bool addToSymbolTable = true); 59 60 // Reports errors via ASSERT. 61 static std::unique_ptr<Statement> Make(const Context& context, 62 Variable* var, 63 const Type* baseType, 64 int arraySize, 65 std::unique_ptr<Expression> value); baseType()66 const Type& baseType() const { 67 return fBaseType; 68 } 69 var()70 const Variable& var() const { 71 // This should never be called after the Variable has been deleted. 72 SkASSERT(fVar); 73 return *fVar; 74 } 75 setVar(const Variable * var)76 void setVar(const Variable* var) { 77 fVar = var; 78 } 79 arraySize()80 int arraySize() const { 81 return fArraySize; 82 } 83 value()84 std::unique_ptr<Expression>& value() { 85 return fValue; 86 } 87 value()88 const std::unique_ptr<Expression>& value() const { 89 return fValue; 90 } 91 92 std::unique_ptr<Statement> clone() const override; 93 94 std::string description() const override; 95 96 private: 97 static bool ErrorCheckAndCoerce(const Context& context, const Variable& var, 98 std::unique_ptr<Expression>& value); 99 100 const Variable* fVar; 101 const Type& fBaseType; 102 int fArraySize; // zero means "not an array" 103 std::unique_ptr<Expression> fValue; 104 // if this VarDeclaration is a clone, it doesn't actually own the associated variable 105 bool fIsClone; 106 107 friend class IRGenerator; 108 109 using INHERITED = Statement; 110 }; 111 112 /** 113 * A variable declaration appearing at global scope. A global declaration like 'int x, y;' produces 114 * two GlobalVarDeclaration elements, each containing the declaration of one variable. 115 */ 116 class GlobalVarDeclaration final : public ProgramElement { 117 public: 118 inline static constexpr Kind kProgramElementKind = Kind::kGlobalVar; 119 GlobalVarDeclaration(std::unique_ptr<Statement> decl)120 GlobalVarDeclaration(std::unique_ptr<Statement> decl) 121 : INHERITED(decl->fLine, kProgramElementKind) 122 , fDeclaration(std::move(decl)) { 123 SkASSERT(this->declaration()->is<VarDeclaration>()); 124 } 125 declaration()126 std::unique_ptr<Statement>& declaration() { 127 return fDeclaration; 128 } 129 declaration()130 const std::unique_ptr<Statement>& declaration() const { 131 return fDeclaration; 132 } 133 clone()134 std::unique_ptr<ProgramElement> clone() const override { 135 return std::make_unique<GlobalVarDeclaration>(this->declaration()->clone()); 136 } 137 description()138 std::string description() const override { 139 return this->declaration()->description(); 140 } 141 142 private: 143 std::unique_ptr<Statement> fDeclaration; 144 145 using INHERITED = ProgramElement; 146 }; 147 148 } // namespace SkSL 149 150 #endif 151