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 within a var declaration statement. For instance, the statement |
20 | * 'int x = 2, y[3];' is a VarDeclarations statement containing two individual VarDeclaration |
21 | * instances. |
22 | */ |
23 | struct VarDeclaration : public Statement { |
24 | VarDeclaration(const Variable* var, |
25 | std::vector<std::unique_ptr<Expression>> sizes, |
26 | std::unique_ptr<Expression> value) |
27 | : INHERITED(var->fOffset, Statement::kVarDeclaration_Kind) |
28 | , fVar(var) |
29 | , fSizes(std::move(sizes)) |
30 | , fValue(std::move(value)) {} |
31 | |
32 | std::unique_ptr<Statement> clone() const override { |
33 | std::vector<std::unique_ptr<Expression>> sizesClone; |
34 | for (const auto& s : fSizes) { |
35 | if (s) { |
36 | sizesClone.push_back(s->clone()); |
37 | } else { |
38 | sizesClone.push_back(nullptr); |
39 | } |
40 | } |
41 | return std::unique_ptr<Statement>(new VarDeclaration(fVar, std::move(sizesClone), |
42 | fValue ? fValue->clone() : nullptr)); |
43 | } |
44 | |
45 | #ifdef SK_DEBUG |
46 | String description() const override { |
47 | String result = fVar->fName; |
48 | for (const auto& size : fSizes) { |
49 | if (size) { |
50 | result += "[" + size->description() + "]" ; |
51 | } else { |
52 | result += "[]" ; |
53 | } |
54 | } |
55 | if (fValue) { |
56 | result += " = " + fValue->description(); |
57 | } |
58 | return result; |
59 | } |
60 | #endif |
61 | |
62 | const Variable* fVar; |
63 | std::vector<std::unique_ptr<Expression>> fSizes; |
64 | std::unique_ptr<Expression> fValue; |
65 | |
66 | typedef Statement INHERITED; |
67 | }; |
68 | |
69 | /** |
70 | * A variable declaration statement, which may consist of one or more individual variables. |
71 | */ |
72 | struct VarDeclarations : public ProgramElement { |
73 | VarDeclarations(int offset, const Type* baseType, |
74 | std::vector<std::unique_ptr<VarDeclaration>> vars) |
75 | : INHERITED(offset, kVar_Kind) |
76 | , fBaseType(*baseType) { |
77 | for (auto& var : vars) { |
78 | fVars.push_back(std::unique_ptr<Statement>(var.release())); |
79 | } |
80 | } |
81 | |
82 | std::unique_ptr<ProgramElement> clone() const override { |
83 | std::vector<std::unique_ptr<VarDeclaration>> cloned; |
84 | for (const auto& v : fVars) { |
85 | cloned.push_back(std::unique_ptr<VarDeclaration>( |
86 | (VarDeclaration*) v->clone().release())); |
87 | } |
88 | return std::unique_ptr<ProgramElement>(new VarDeclarations(fOffset, &fBaseType, |
89 | std::move(cloned))); |
90 | } |
91 | |
92 | #ifdef SK_DEBUG |
93 | String description() const override { |
94 | if (!fVars.size()) { |
95 | return String(); |
96 | } |
97 | String result = ((VarDeclaration&) *fVars[0]).fVar->fModifiers.description() + |
98 | fBaseType.description() + " " ; |
99 | String separator; |
100 | for (const auto& var : fVars) { |
101 | result += separator; |
102 | separator = ", " ; |
103 | result += var->description(); |
104 | } |
105 | return result; |
106 | } |
107 | #endif |
108 | |
109 | const Type& fBaseType; |
110 | // this *should* be a vector of unique_ptr<VarDeclaration>, but it significantly simplifies the |
111 | // CFG to only have to worry about unique_ptr<Statement> |
112 | std::vector<std::unique_ptr<Statement>> fVars; |
113 | |
114 | typedef ProgramElement INHERITED; |
115 | }; |
116 | |
117 | } // namespace |
118 | |
119 | #endif |
120 | |