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 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->fOffset, 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 // Does proper error checking and type coercion; reports errors via ErrorReporter. 49 static std::unique_ptr<Statement> Convert(const Context& context, 50 Variable* var, 51 std::unique_ptr<Expression> value); 52 53 // Reports errors via ASSERT. 54 static std::unique_ptr<Statement> Make(const Context& context, 55 Variable* var, 56 const Type* baseType, 57 int arraySize, 58 std::unique_ptr<Expression> value); baseType()59 const Type& baseType() const { 60 return fBaseType; 61 } 62 var()63 const Variable& var() const { 64 // This should never be called after the Variable has been deleted. 65 SkASSERT(fVar); 66 return *fVar; 67 } 68 setVar(const Variable * var)69 void setVar(const Variable* var) { 70 fVar = var; 71 } 72 arraySize()73 int arraySize() const { 74 return fArraySize; 75 } 76 value()77 std::unique_ptr<Expression>& value() { 78 return fValue; 79 } 80 value()81 const std::unique_ptr<Expression>& value() const { 82 return fValue; 83 } 84 85 std::unique_ptr<Statement> clone() const override; 86 87 String description() const override; 88 89 private: 90 const Variable* fVar; 91 const Type& fBaseType; 92 int fArraySize; // zero means "not an array", Type::kUnsizedArray means var[] 93 std::unique_ptr<Expression> fValue; 94 95 friend class IRGenerator; 96 97 using INHERITED = Statement; 98 }; 99 100 /** 101 * A variable declaration appearing at global scope. A global declaration like 'int x, y;' produces 102 * two GlobalVarDeclaration elements, each containing the declaration of one variable. 103 */ 104 class GlobalVarDeclaration final : public ProgramElement { 105 public: 106 static constexpr Kind kProgramElementKind = Kind::kGlobalVar; 107 GlobalVarDeclaration(std::unique_ptr<Statement> decl)108 GlobalVarDeclaration(std::unique_ptr<Statement> decl) 109 : INHERITED(decl->fOffset, kProgramElementKind) 110 , fDeclaration(std::move(decl)) { 111 SkASSERT(this->declaration()->is<VarDeclaration>()); 112 } 113 declaration()114 std::unique_ptr<Statement>& declaration() { 115 return fDeclaration; 116 } 117 declaration()118 const std::unique_ptr<Statement>& declaration() const { 119 return fDeclaration; 120 } 121 clone()122 std::unique_ptr<ProgramElement> clone() const override { 123 return std::make_unique<GlobalVarDeclaration>(this->declaration()->clone()); 124 } 125 description()126 String description() const override { 127 return this->declaration()->description(); 128 } 129 130 private: 131 std::unique_ptr<Statement> fDeclaration; 132 133 using INHERITED = ProgramElement; 134 }; 135 136 } // namespace SkSL 137 138 #endif 139