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 "src/sksl/ir/SkSLExpression.h" 12 #include "src/sksl/ir/SkSLProgramElement.h" 13 #include "src/sksl/ir/SkSLStatement.h" 14 #include "src/sksl/ir/SkSLVariable.h" 15 16 namespace SkSL { 17 18 /** 19 * A single variable declaration statement. Multiple variables declared together are expanded to 20 * separate (sequential) statements. For instance, the SkSL 'int x = 2, y[3];' produces two 21 * VarDeclaration instances (wrapped in an unscoped Block). 22 */ 23 class VarDeclaration final : public Statement { 24 public: 25 static constexpr Kind kStatementKind = Kind::kVarDeclaration; 26 VarDeclaration(const Variable * var,const Type * baseType,ExpressionArray sizes,std::unique_ptr<Expression> value)27 VarDeclaration(const Variable* var, 28 const Type* baseType, 29 ExpressionArray sizes, 30 std::unique_ptr<Expression> value) 31 : INHERITED(var->fOffset, kStatementKind) 32 , fVar(var) 33 , fBaseType(*baseType) 34 , fSizes(std::move(sizes)) 35 , fValue(std::move(value)) {} 36 baseType()37 const Type& baseType() const { 38 return fBaseType; 39 } 40 var()41 const Variable& var() const { 42 return *fVar; 43 } 44 setVar(const Variable * var)45 void setVar(const Variable* var) { 46 fVar = var; 47 } 48 sizes()49 const ExpressionArray& sizes() const { 50 return fSizes; 51 } 52 value()53 std::unique_ptr<Expression>& value() { 54 return fValue; 55 } 56 value()57 const std::unique_ptr<Expression>& value() const { 58 return fValue; 59 } 60 clone()61 std::unique_ptr<Statement> clone() const override { 62 ExpressionArray sizesClone; 63 sizesClone.reserve_back(this->sizes().count()); 64 for (const std::unique_ptr<Expression>& size : this->sizes()) { 65 if (size) { 66 sizesClone.push_back(size->clone()); 67 } else { 68 sizesClone.push_back(nullptr); 69 } 70 } 71 return std::make_unique<VarDeclaration>(&this->var(), 72 &this->baseType(), 73 std::move(sizesClone), 74 this->value() ? this->value()->clone() : nullptr); 75 } 76 description()77 String description() const override { 78 String result = this->var().modifiers().description() + this->baseType().description() + 79 " " + this->var().name(); 80 for (const std::unique_ptr<Expression>& size : this->sizes()) { 81 if (size) { 82 result += "[" + size->description() + "]"; 83 } else { 84 result += "[]"; 85 } 86 } 87 if (this->value()) { 88 result += " = " + this->value()->description(); 89 } 90 result += ";"; 91 return result; 92 } 93 94 private: 95 const Variable* fVar; 96 const Type& fBaseType; 97 ExpressionArray fSizes; 98 std::unique_ptr<Expression> fValue; 99 100 using INHERITED = Statement; 101 }; 102 103 /** 104 * A variable declaration appearing at global scope. A global declaration like 'int x, y;' produces 105 * two GlobalVarDeclaration elements, each containing the declaration of one variable. 106 */ 107 class GlobalVarDeclaration final : public ProgramElement { 108 public: 109 static constexpr Kind kProgramElementKind = Kind::kGlobalVar; 110 GlobalVarDeclaration(int offset,std::unique_ptr<Statement> decl)111 GlobalVarDeclaration(int offset, std::unique_ptr<Statement> decl) 112 : INHERITED(offset, kProgramElementKind) 113 , fDeclaration(std::move(decl)) { 114 SkASSERT(this->declaration()->is<VarDeclaration>()); 115 } 116 declaration()117 std::unique_ptr<Statement>& declaration() { 118 return fDeclaration; 119 } 120 declaration()121 const std::unique_ptr<Statement>& declaration() const { 122 return fDeclaration; 123 } 124 clone()125 std::unique_ptr<ProgramElement> clone() const override { 126 return std::make_unique<GlobalVarDeclaration>(fOffset, this->declaration()->clone()); 127 } 128 description()129 String description() const override { 130 return this->declaration()->description(); 131 } 132 133 private: 134 std::unique_ptr<Statement> fDeclaration; 135 136 using INHERITED = ProgramElement; 137 }; 138 139 } // namespace SkSL 140 141 #endif 142