• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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