blob: 8a94441b5ecd0d49d74b515dea7706d46d2b96dc [file] [log] [blame]
/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SKSL_VARDECLARATIONS
#define SKSL_VARDECLARATIONS
#include "src/sksl/ir/SkSLExpression.h"
#include "src/sksl/ir/SkSLProgramElement.h"
#include "src/sksl/ir/SkSLStatement.h"
#include "src/sksl/ir/SkSLVariable.h"
namespace SkSL {
/**
* A single variable declaration within a var declaration statement. For instance, the statement
* 'int x = 2, y[3];' is a VarDeclarations statement containing two individual VarDeclaration
* instances.
*/
struct VarDeclaration : public Statement {
static constexpr Kind kStatementKind = Kind::kVarDeclaration;
VarDeclaration(const Variable* var,
std::vector<std::unique_ptr<Expression>> sizes,
std::unique_ptr<Expression> value)
: INHERITED(var->fOffset, kStatementKind)
, fVar(var)
, fSizes(std::move(sizes))
, fValue(std::move(value)) {}
std::unique_ptr<Statement> clone() const override {
std::vector<std::unique_ptr<Expression>> sizesClone;
for (const auto& s : fSizes) {
if (s) {
sizesClone.push_back(s->clone());
} else {
sizesClone.push_back(nullptr);
}
}
return std::unique_ptr<Statement>(new VarDeclaration(fVar, std::move(sizesClone),
fValue ? fValue->clone() : nullptr));
}
String description() const override {
String result = fVar->fModifiers.description() + fVar->type().name() + " " + fVar->fName;
for (const auto& size : fSizes) {
if (size) {
result += "[" + size->description() + "]";
} else {
result += "[]";
}
}
if (fValue) {
result += " = " + fValue->description();
}
return result;
}
const Variable* fVar;
std::vector<std::unique_ptr<Expression>> fSizes;
std::unique_ptr<Expression> fValue;
using INHERITED = Statement;
};
/**
* A variable declaration statement, which may consist of one or more individual variables.
*/
struct VarDeclarations : public ProgramElement {
static constexpr Kind kProgramElementKind = Kind::kVar;
VarDeclarations(int offset, const Type* baseType,
std::vector<std::unique_ptr<VarDeclaration>> vars)
: INHERITED(offset, kProgramElementKind)
, fBaseType(*baseType) {
for (auto& var : vars) {
fVars.push_back(std::unique_ptr<Statement>(var.release()));
}
}
std::unique_ptr<ProgramElement> clone() const override {
std::vector<std::unique_ptr<VarDeclaration>> cloned;
for (const auto& v : fVars) {
cloned.push_back(std::unique_ptr<VarDeclaration>(
(VarDeclaration*) v->clone().release()));
}
return std::unique_ptr<ProgramElement>(new VarDeclarations(fOffset, &fBaseType,
std::move(cloned)));
}
String description() const override {
if (!fVars.size()) {
return String();
}
String result;
for (const auto& var : fVars) {
if (var->kind() != Statement::Kind::kNop) {
SkASSERT(var->kind() == Statement::Kind::kVarDeclaration);
result = ((const VarDeclaration&) *var).fVar->fModifiers.description();
break;
}
}
result += fBaseType.description() + " ";
String separator;
for (const auto& rawVar : fVars) {
if (rawVar->kind() == Statement::Kind::kNop) {
continue;
}
SkASSERT(rawVar->kind() == Statement::Kind::kVarDeclaration);
VarDeclaration& var = (VarDeclaration&) *rawVar;
result += separator;
separator = ", ";
result += var.fVar->fName;
if (var.fValue) {
result += " = " + var.fValue->description();
}
}
return result;
}
const Type& fBaseType;
// this *should* be a vector of unique_ptr<VarDeclaration>, but it significantly simplifies the
// CFG to only have to worry about unique_ptr<Statement>
std::vector<std::unique_ptr<Statement>> fVars;
using INHERITED = ProgramElement;
};
} // namespace SkSL
#endif