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
16namespace 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 */
23struct 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 */
72struct 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