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 VarDeclaration(const Variable * var,const Type * baseType,int arraySize,std::unique_ptr<Expression> value)31 VarDeclaration(const Variable* var, 32 const Type* baseType, 33 int arraySize, 34 std::unique_ptr<Expression> value) 35 : INHERITED(var->fLine, kStatementKind) 36 , fVar(var) 37 , fBaseType(*baseType) 38 , fArraySize(arraySize) 39 , fValue(std::move(value)) {} 40 ~VarDeclaration()41 ~VarDeclaration() override { 42 // Unhook this VarDeclaration from its associated Variable, since we're being deleted. 43 if (fVar) { 44 fVar->detachDeadVarDeclaration(); 45 } 46 } 47 48 // Checks the modifiers, baseType, and storage for compatibility with one another and reports 49 // errors if needed. This method is implicitly called during Convert(), but is also explicitly 50 // called while processing interface block fields. 51 static void ErrorCheck(const Context& context, int line, const Modifiers& modifiers, 52 const Type* baseType, Variable::Storage storage); 53 54 // Does proper error checking and type coercion; reports errors via ErrorReporter. 55 static std::unique_ptr<Statement> Convert(const Context& context, std::unique_ptr<Variable> var, 56 std::unique_ptr<Expression> value, bool addToSymbolTable = true); 57 58 // Reports errors via ASSERT. 59 static std::unique_ptr<Statement> Make(const Context& context, 60 Variable* var, 61 const Type* baseType, 62 int arraySize, 63 std::unique_ptr<Expression> value); baseType()64 const Type& baseType() const { 65 return fBaseType; 66 } 67 var()68 const Variable& var() const { 69 // This should never be called after the Variable has been deleted. 70 SkASSERT(fVar); 71 return *fVar; 72 } 73 setVar(const Variable * var)74 void setVar(const Variable* var) { 75 fVar = var; 76 } 77 arraySize()78 int arraySize() const { 79 return fArraySize; 80 } 81 value()82 std::unique_ptr<Expression>& value() { 83 return fValue; 84 } 85 value()86 const std::unique_ptr<Expression>& value() const { 87 return fValue; 88 } 89 90 std::unique_ptr<Statement> clone() const override; 91 92 String description() const override; 93 94 private: 95 static bool ErrorCheckAndCoerce(const Context& context, const Variable& var, 96 std::unique_ptr<Expression>& value); 97 98 const Variable* fVar; 99 const Type& fBaseType; 100 int fArraySize; // zero means "not an array" 101 std::unique_ptr<Expression> fValue; 102 103 friend class IRGenerator; 104 105 using INHERITED = Statement; 106 }; 107 108 /** 109 * A variable declaration appearing at global scope. A global declaration like 'int x, y;' produces 110 * two GlobalVarDeclaration elements, each containing the declaration of one variable. 111 */ 112 class GlobalVarDeclaration final : public ProgramElement { 113 public: 114 inline static constexpr Kind kProgramElementKind = Kind::kGlobalVar; 115 GlobalVarDeclaration(std::unique_ptr<Statement> decl)116 GlobalVarDeclaration(std::unique_ptr<Statement> decl) 117 : INHERITED(decl->fLine, kProgramElementKind) 118 , fDeclaration(std::move(decl)) { 119 SkASSERT(this->declaration()->is<VarDeclaration>()); 120 } 121 declaration()122 std::unique_ptr<Statement>& declaration() { 123 return fDeclaration; 124 } 125 declaration()126 const std::unique_ptr<Statement>& declaration() const { 127 return fDeclaration; 128 } 129 clone()130 std::unique_ptr<ProgramElement> clone() const override { 131 return std::make_unique<GlobalVarDeclaration>(this->declaration()->clone()); 132 } 133 description()134 String description() const override { 135 return this->declaration()->description(); 136 } 137 138 private: 139 std::unique_ptr<Statement> fDeclaration; 140 141 using INHERITED = ProgramElement; 142 }; 143 144 } // namespace SkSL 145 146 #endif 147