• 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 
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