ASTDeclaration& decl = *parsed[i];
switch (decl.fKind) {
case ASTDeclaration::kVar_Kind: {
- std::unique_ptr<VarDeclaration> s = fIRGenerator->convertVarDeclaration(
- (ASTVarDeclaration&) decl,
+ std::unique_ptr<VarDeclarations> s = fIRGenerator->convertVarDeclarations(
+ (ASTVarDeclarations&) decl,
Variable::kGlobal_Storage);
if (s) {
result->push_back(std::move(s));
this->writeLine("};");
}
-void GLSLCodeGenerator::writeVarDeclaration(const VarDeclaration& decl) {
+void GLSLCodeGenerator::writeVarDeclarations(const VarDeclarations& decl) {
ASSERT(decl.fVars.size() > 0);
- this->writeModifiers(decl.fVars[0]->fModifiers);
+ this->writeModifiers(decl.fVars[0].fVar->fModifiers);
this->writeType(decl.fBaseType);
std::string separator = " ";
- for (size_t i = 0; i < decl.fVars.size(); i++) {
- ASSERT(decl.fVars[i]->fModifiers == decl.fVars[0]->fModifiers);
+ for (const auto& var : decl.fVars) {
+ ASSERT(var.fVar->fModifiers == decl.fVars[0].fVar->fModifiers);
this->write(separator);
separator = ", ";
- this->write(decl.fVars[i]->fName);
- for (const auto& size : decl.fSizes[i]) {
+ this->write(var.fVar->fName);
+ for (const auto& size : var.fSizes) {
this->write("[");
this->writeExpression(*size, kTopLevel_Precedence);
this->write("]");
}
- if (decl.fValues[i]) {
+ if (var.fValue) {
this->write(" = ");
- this->writeExpression(*decl.fValues[i], kTopLevel_Precedence);
+ this->writeExpression(*var.fValue, kTopLevel_Precedence);
}
}
this->write(";");
case Statement::kReturn_Kind:
this->writeReturnStatement((ReturnStatement&) s);
break;
- case Statement::kVarDeclaration_Kind:
- this->writeVarDeclaration(*((VarDeclarationStatement&) s).fDeclaration);
+ case Statement::kVarDeclarations_Kind:
+ this->writeVarDeclarations(*((VarDeclarationsStatement&) s).fDeclaration);
break;
case Statement::kIf_Kind:
this->writeIfStatement((IfStatement&) s);
this->writeExtension((Extension&) *e);
break;
case ProgramElement::kVar_Kind: {
- VarDeclaration& decl = (VarDeclaration&) *e;
- if (decl.fVars.size() > 0 && decl.fVars[0]->fModifiers.fLayout.fBuiltin == -1) {
- this->writeVarDeclaration(decl);
+ VarDeclarations& decl = (VarDeclarations&) *e;
+ if (decl.fVars.size() > 0 &&
+ decl.fVars[0].fVar->fModifiers.fLayout.fBuiltin == -1) {
+ this->writeVarDeclarations(decl);
this->writeLine();
}
break;
void writeGlobalVars(const VarDeclaration& vs);
- void writeVarDeclaration(const VarDeclaration& decl);
+ void writeVarDeclarations(const VarDeclarations& decl);
void writeVariableReference(const VariableReference& ref);
std::unique_ptr<Statement> IRGenerator::convertVarDeclarationStatement(
const ASTVarDeclarationStatement& s) {
- auto decl = this->convertVarDeclaration(*s.fDeclaration, Variable::kLocal_Storage);
+ auto decl = this->convertVarDeclarations(*s.fDeclarations, Variable::kLocal_Storage);
if (!decl) {
return nullptr;
}
- return std::unique_ptr<Statement>(new VarDeclarationStatement(std::move(decl)));
+ return std::unique_ptr<Statement>(new VarDeclarationsStatement(std::move(decl)));
}
Modifiers IRGenerator::convertModifiers(const ASTModifiers& modifiers) {
return Modifiers(modifiers);
}
-std::unique_ptr<VarDeclaration> IRGenerator::convertVarDeclaration(const ASTVarDeclaration& decl,
- Variable::Storage storage) {
- std::vector<const Variable*> variables;
- std::vector<std::vector<std::unique_ptr<Expression>>> sizes;
- std::vector<std::unique_ptr<Expression>> values;
+std::unique_ptr<VarDeclarations> IRGenerator::convertVarDeclarations(const ASTVarDeclarations& decl,
+ Variable::Storage storage) {
+ std::vector<VarDeclaration> variables;
const Type* baseType = this->convertType(*decl.fType);
if (!baseType) {
return nullptr;
}
- for (size_t i = 0; i < decl.fNames.size(); i++) {
+ for (const auto& varDecl : decl.fVars) {
Modifiers modifiers = this->convertModifiers(decl.fModifiers);
const Type* type = baseType;
ASSERT(type->kind() != Type::kArray_Kind);
- std::vector<std::unique_ptr<Expression>> currentVarSizes;
- for (size_t j = 0; j < decl.fSizes[i].size(); j++) {
- if (decl.fSizes[i][j]) {
- ASTExpression& rawSize = *decl.fSizes[i][j];
- auto size = this->coerce(this->convertExpression(rawSize), *fContext.fInt_Type);
+ std::vector<std::unique_ptr<Expression>> sizes;
+ for (const auto& rawSize : varDecl.fSizes) {
+ if (rawSize) {
+ auto size = this->coerce(this->convertExpression(*rawSize), *fContext.fInt_Type);
if (!size) {
return nullptr;
}
}
type = new Type(name, Type::kArray_Kind, *type, (int) count);
fSymbolTable->takeOwnership((Type*) type);
- currentVarSizes.push_back(std::move(size));
+ sizes.push_back(std::move(size));
} else {
type = new Type(type->fName + "[]", Type::kArray_Kind, *type, -1);
fSymbolTable->takeOwnership((Type*) type);
- currentVarSizes.push_back(nullptr);
+ sizes.push_back(nullptr);
}
}
- auto var = std::unique_ptr<Variable>(new Variable(decl.fPosition, modifiers, decl.fNames[i],
+ auto var = std::unique_ptr<Variable>(new Variable(decl.fPosition, modifiers, varDecl.fName,
*type, storage));
std::unique_ptr<Expression> value;
- if (decl.fValues[i]) {
- value = this->convertExpression(*decl.fValues[i]);
+ if (varDecl.fValue) {
+ value = this->convertExpression(*varDecl.fValue);
if (!value) {
return nullptr;
}
value = this->coerce(std::move(value), *type);
}
- if ("gl_FragCoord" == decl.fNames[i] && (*fSymbolTable)[decl.fNames[i]]) {
+ if ("gl_FragCoord" == varDecl.fName && (*fSymbolTable)[varDecl.fName]) {
// already defined, just update the modifiers
- Variable* old = (Variable*) (*fSymbolTable)[decl.fNames[i]];
+ Variable* old = (Variable*) (*fSymbolTable)[varDecl.fName];
old->fModifiers = var->fModifiers;
} else {
- variables.push_back(var.get());
- fSymbolTable->add(decl.fNames[i], std::move(var));
- values.push_back(std::move(value));
- sizes.push_back(std::move(currentVarSizes));
+ variables.emplace_back(var.get(), std::move(sizes), std::move(value));
+ fSymbolTable->add(varDecl.fName, std::move(var));
}
}
- return std::unique_ptr<VarDeclaration>(new VarDeclaration(decl.fPosition,
- baseType,
- std::move(variables),
- std::move(sizes),
- std::move(values)));
+ return std::unique_ptr<VarDeclarations>(new VarDeclarations(decl.fPosition,
+ baseType,
+ std::move(variables)));
}
std::unique_ptr<Statement> IRGenerator::convertIf(const ASTIfStatement& s) {
Modifiers mods = this->convertModifiers(intf.fModifiers);
std::vector<Type::Field> fields;
for (size_t i = 0; i < intf.fDeclarations.size(); i++) {
- std::unique_ptr<VarDeclaration> decl = this->convertVarDeclaration(
+ std::unique_ptr<VarDeclarations> decl = this->convertVarDeclarations(
*intf.fDeclarations[i],
Variable::kGlobal_Storage);
- for (size_t j = 0; j < decl->fVars.size(); j++) {
- fields.push_back(Type::Field(decl->fVars[j]->fModifiers, decl->fVars[j]->fName,
- &decl->fVars[j]->fType));
- if (decl->fValues[j]) {
+ for (const auto& var : decl->fVars) {
+ fields.push_back(Type::Field(var.fVar->fModifiers, var.fVar->fName,
+ &var.fVar->fType));
+ if (var.fValue) {
fErrors.error(decl->fPosition,
"initializers are not permitted on interface block fields");
}
- if (decl->fVars[j]->fModifiers.fFlags & (Modifiers::kIn_Flag |
- Modifiers::kOut_Flag |
- Modifiers::kUniform_Flag |
- Modifiers::kConst_Flag)) {
- fErrors.error(decl->fPosition,
+ if (var.fVar->fModifiers.fFlags & (Modifiers::kIn_Flag |
+ Modifiers::kOut_Flag |
+ Modifiers::kUniform_Flag |
+ Modifiers::kConst_Flag)) {
+ fErrors.error(decl->fPosition,
"interface block fields may not have storage qualifiers");
}
}
IRGenerator(const Context* context, std::shared_ptr<SymbolTable> root,
ErrorReporter& errorReporter);
- std::unique_ptr<VarDeclaration> convertVarDeclaration(const ASTVarDeclaration& decl,
- Variable::Storage storage);
+ std::unique_ptr<VarDeclarations> convertVarDeclarations(const ASTVarDeclarations& decl,
+ Variable::Storage storage);
std::unique_ptr<FunctionDefinition> convertFunction(const ASTFunction& f);
std::unique_ptr<Statement> convertStatement(const ASTStatement& statement);
std::unique_ptr<Expression> convertExpression(const ASTExpression& expression);
}
/* modifiers type IDENTIFIER varDeclarationEnd */
-std::unique_ptr<ASTVarDeclaration> Parser::varDeclaration() {
+std::unique_ptr<ASTVarDeclarations> Parser::varDeclarations() {
ASTModifiers modifiers = this->modifiers();
std::unique_ptr<ASTType> type(this->type());
if (!type) {
}
std::vector<Type::Field> fields;
while (this->peek().fKind != Token::RBRACE) {
- std::unique_ptr<ASTVarDeclaration> decl = this->varDeclaration();
+ std::unique_ptr<ASTVarDeclarations> decl = this->varDeclarations();
if (!decl) {
return nullptr;
}
- for (size_t i = 0; i < decl->fNames.size(); i++) {
+ for (const auto& var : decl->fVars) {
auto type = (const Type*) fTypes[decl->fType->fName];
- for (int j = (int) decl->fSizes[i].size() - 1; j >= 0; j--) {
- if (decl->fSizes[i][j]->fKind != ASTExpression::kInt_Kind) {
+ for (int i = (int) var.fSizes.size() - 1; i >= 0; i--) {
+ if (var.fSizes[i]->fKind != ASTExpression::kInt_Kind) {
this->error(decl->fPosition, "array size in struct field must be a constant");
}
- uint64_t columns = ((ASTIntLiteral&) *decl->fSizes[i][j]).fValue;
+ uint64_t columns = ((ASTIntLiteral&) *var.fSizes[i]).fValue;
std::string name = type->name() + "[" + to_string(columns) + "]";
type = new Type(name, Type::kArray_Kind, *type, (int) columns);
fTypes.takeOwnership((Type*) type);
}
- fields.push_back(Type::Field(decl->fModifiers, decl->fNames[i], type));
- if (decl->fValues[i]) {
+ fields.push_back(Type::Field(decl->fModifiers, var.fName, type));
+ if (var.fValue) {
this->error(decl->fPosition, "initializers are not permitted on struct fields");
}
}
}
/* structDeclaration ((IDENTIFIER varDeclarationEnd) | SEMICOLON) */
-std::unique_ptr<ASTVarDeclaration> Parser::structVarDeclaration(ASTModifiers modifiers) {
+std::unique_ptr<ASTVarDeclarations> Parser::structVarDeclaration(ASTModifiers modifiers) {
std::unique_ptr<ASTType> type = this->structDeclaration();
if (!type) {
return nullptr;
}
if (peek().fKind == Token::IDENTIFIER) {
Token name = this->nextToken();
- std::unique_ptr<ASTVarDeclaration> result = this->varDeclarationEnd(modifiers,
- std::move(type),
- std::move(name.fText));
+ std::unique_ptr<ASTVarDeclarations> result = this->varDeclarationEnd(modifiers,
+ std::move(type),
+ std::move(name.fText));
if (result) {
- for (size_t i = 0; i < result->fValues.size(); i++) {
- if (result->fValues[i]) {
- this->error(result->fValues[i]->fPosition,
+ for (const auto& var : result->fVars) {
+ if (var.fValue) {
+ this->error(var.fValue->fPosition,
"struct variables cannot be initialized");
}
}
/* (LBRACKET expression? RBRACKET)* (EQ expression)? (COMMA IDENTIFER
(LBRACKET expression? RBRACKET)* (EQ expression)?)* SEMICOLON */
-std::unique_ptr<ASTVarDeclaration> Parser::varDeclarationEnd(ASTModifiers mods,
- std::unique_ptr<ASTType> type,
- std::string name) {
- std::vector<std::string> names;
- std::vector<std::vector<std::unique_ptr<ASTExpression>>> sizes;
- names.push_back(name);
+std::unique_ptr<ASTVarDeclarations> Parser::varDeclarationEnd(ASTModifiers mods,
+ std::unique_ptr<ASTType> type,
+ std::string name) {
+ std::vector<ASTVarDeclaration> vars;
std::vector<std::unique_ptr<ASTExpression>> currentVarSizes;
while (this->peek().fKind == Token::LBRACKET) {
this->nextToken();
}
}
}
- sizes.push_back(std::move(currentVarSizes));
- std::vector<std::unique_ptr<ASTExpression>> values;
+ std::unique_ptr<ASTExpression> value;
if (this->peek().fKind == Token::EQ) {
this->nextToken();
- std::unique_ptr<ASTExpression> value(this->expression());
+ value = this->expression();
if (!value) {
return nullptr;
}
- values.push_back(std::move(value));
- } else {
- values.push_back(nullptr);
}
+ vars.emplace_back(std::move(name), std::move(currentVarSizes), std::move(value));
while (this->peek().fKind == Token::COMMA) {
this->nextToken();
Token name;
if (!this->expect(Token::IDENTIFIER, "an identifier", &name)) {
return nullptr;
}
- names.push_back(name.fText);
currentVarSizes.clear();
+ value.reset();
while (this->peek().fKind == Token::LBRACKET) {
this->nextToken();
if (this->peek().fKind == Token::RBRACKET) {
}
}
}
- sizes.push_back(std::move(currentVarSizes));
if (this->peek().fKind == Token::EQ) {
this->nextToken();
- std::unique_ptr<ASTExpression> value(this->expression());
+ value = this->expression();
if (!value) {
return nullptr;
}
- values.push_back(std::move(value));
- } else {
- values.push_back(nullptr);
}
+ vars.emplace_back(std::move(name.fText), std::move(currentVarSizes), std::move(value));
}
if (!this->expect(Token::SEMICOLON, "';'")) {
return nullptr;
}
- return std::unique_ptr<ASTVarDeclaration>(new ASTVarDeclaration(std::move(mods),
- std::move(type),
- std::move(names),
- std::move(sizes),
- std::move(values)));
+ return std::unique_ptr<ASTVarDeclarations>(new ASTVarDeclarations(std::move(mods),
+ std::move(type),
+ std::move(vars)));
}
/* modifiers type IDENTIFIER (LBRACKET INT_LITERAL RBRACKET)? */
case Token::HIGHP: // fall through
case Token::MEDIUMP: // fall through
case Token::LOWP: {
- auto decl = this->varDeclaration();
+ auto decl = this->varDeclarations();
if (!decl) {
return nullptr;
}
}
case Token::IDENTIFIER:
if (this->isType(start.fText)) {
- auto decl = this->varDeclaration();
+ auto decl = this->varDeclarations();
if (!decl) {
return nullptr;
}
return nullptr;
}
this->nextToken();
- std::vector<std::unique_ptr<ASTVarDeclaration>> decls;
+ std::vector<std::unique_ptr<ASTVarDeclarations>> decls;
while (this->peek().fKind != Token::RBRACE) {
- std::unique_ptr<ASTVarDeclaration> decl = this->varDeclaration();
+ std::unique_ptr<ASTVarDeclarations> decl = this->varDeclarations();
if (!decl) {
return nullptr;
}
break;
case Token::CONST:
initializer = std::unique_ptr<ASTStatement>(new ASTVarDeclarationStatement(
- this->varDeclaration()));
+ this->varDeclarations()));
break;
case Token::IDENTIFIER:
if (this->isType(nextToken.fText)) {
initializer = std::unique_ptr<ASTStatement>(new ASTVarDeclarationStatement(
- this->varDeclaration()));
+ this->varDeclarations()));
break;
}
// fall through
struct ASTSuffix;
struct ASTType;
struct ASTWhileStatement;
-struct ASTVarDeclaration;
+struct ASTVarDeclarations;
class SymbolTable;
/**
std::unique_ptr<ASTDeclaration> declaration();
- std::unique_ptr<ASTVarDeclaration> varDeclaration();
+ std::unique_ptr<ASTVarDeclarations> varDeclarations();
std::unique_ptr<ASTType> structDeclaration();
- std::unique_ptr<ASTVarDeclaration> structVarDeclaration(ASTModifiers modifiers);
+ std::unique_ptr<ASTVarDeclarations> structVarDeclaration(ASTModifiers modifiers);
- std::unique_ptr<ASTVarDeclaration> varDeclarationEnd(ASTModifiers modifiers,
- std::unique_ptr<ASTType> type,
- std::string name);
+ std::unique_ptr<ASTVarDeclarations> varDeclarationEnd(ASTModifiers modifiers,
+ std::unique_ptr<ASTType> type,
+ std::string name);
std::unique_ptr<ASTParameter> parameter();
return result;
}
-void SPIRVCodeGenerator::writeGlobalVars(const VarDeclaration& decl, std::ostream& out) {
+void SPIRVCodeGenerator::writeGlobalVars(const VarDeclarations& decl, std::ostream& out) {
for (size_t i = 0; i < decl.fVars.size(); i++) {
- if (!decl.fVars[i]->fIsReadFrom && !decl.fVars[i]->fIsWrittenTo &&
- !(decl.fVars[i]->fModifiers.fFlags & (Modifiers::kIn_Flag |
- Modifiers::kOut_Flag |
- Modifiers::kUniform_Flag))) {
+ const VarDeclaration& varDecl = decl.fVars[i];
+ const Variable* var = varDecl.fVar;
+ if (!var->fIsReadFrom && !var->fIsWrittenTo &&
+ !(var->fModifiers.fFlags & (Modifiers::kIn_Flag |
+ Modifiers::kOut_Flag |
+ Modifiers::kUniform_Flag))) {
// variable is dead and not an input / output var (the Vulkan debug layers complain if
// we elide an interface var, even if it's dead)
continue;
}
SpvStorageClass_ storageClass;
- if (decl.fVars[i]->fModifiers.fFlags & Modifiers::kIn_Flag) {
+ if (var->fModifiers.fFlags & Modifiers::kIn_Flag) {
storageClass = SpvStorageClassInput;
- } else if (decl.fVars[i]->fModifiers.fFlags & Modifiers::kOut_Flag) {
+ } else if (var->fModifiers.fFlags & Modifiers::kOut_Flag) {
storageClass = SpvStorageClassOutput;
- } else if (decl.fVars[i]->fModifiers.fFlags & Modifiers::kUniform_Flag) {
- if (decl.fVars[i]->fType.kind() == Type::kSampler_Kind) {
+ } else if (var->fModifiers.fFlags & Modifiers::kUniform_Flag) {
+ if (var->fType.kind() == Type::kSampler_Kind) {
storageClass = SpvStorageClassUniformConstant;
} else {
storageClass = SpvStorageClassUniform;
storageClass = SpvStorageClassPrivate;
}
SpvId id = this->nextId();
- fVariableMap[decl.fVars[i]] = id;
- SpvId type = this->getPointerType(decl.fVars[i]->fType, storageClass);
+ fVariableMap[var] = id;
+ SpvId type = this->getPointerType(var->fType, storageClass);
this->writeInstruction(SpvOpVariable, type, id, storageClass, fConstantBuffer);
- this->writeInstruction(SpvOpName, id, decl.fVars[i]->fName.c_str(), fNameBuffer);
- if (decl.fVars[i]->fType.kind() == Type::kMatrix_Kind) {
+ this->writeInstruction(SpvOpName, id, var->fName.c_str(), fNameBuffer);
+ if (var->fType.kind() == Type::kMatrix_Kind) {
this->writeInstruction(SpvOpMemberDecorate, id, (SpvId) i, SpvDecorationColMajor,
fDecorationBuffer);
this->writeInstruction(SpvOpMemberDecorate, id, (SpvId) i, SpvDecorationMatrixStride,
- (SpvId) decl.fVars[i]->fType.stride(), fDecorationBuffer);
+ (SpvId) var->fType.stride(), fDecorationBuffer);
}
- if (decl.fValues[i]) {
+ if (varDecl.fValue) {
ASSERT(!fCurrentBlock);
fCurrentBlock = -1;
- SpvId value = this->writeExpression(*decl.fValues[i], fGlobalInitializersBuffer);
+ SpvId value = this->writeExpression(*varDecl.fValue, fGlobalInitializersBuffer);
this->writeInstruction(SpvOpStore, id, value, fGlobalInitializersBuffer);
fCurrentBlock = 0;
}
- this->writeLayout(decl.fVars[i]->fModifiers.fLayout, id);
+ this->writeLayout(var->fModifiers.fLayout, id);
}
}
-void SPIRVCodeGenerator::writeVarDeclaration(const VarDeclaration& decl, std::ostream& out) {
- for (size_t i = 0; i < decl.fVars.size(); i++) {
+void SPIRVCodeGenerator::writeVarDeclarations(const VarDeclarations& decl, std::ostream& out) {
+ for (const auto& varDecl : decl.fVars) {
+ const Variable* var = varDecl.fVar;
SpvId id = this->nextId();
- fVariableMap[decl.fVars[i]] = id;
- SpvId type = this->getPointerType(decl.fVars[i]->fType, SpvStorageClassFunction);
+ fVariableMap[var] = id;
+ SpvId type = this->getPointerType(var->fType, SpvStorageClassFunction);
this->writeInstruction(SpvOpVariable, type, id, SpvStorageClassFunction, fVariableBuffer);
- this->writeInstruction(SpvOpName, id, decl.fVars[i]->fName.c_str(), fNameBuffer);
- if (decl.fValues[i]) {
- SpvId value = this->writeExpression(*decl.fValues[i], out);
+ this->writeInstruction(SpvOpName, id, var->fName.c_str(), fNameBuffer);
+ if (varDecl.fValue) {
+ SpvId value = this->writeExpression(*varDecl.fValue, out);
this->writeInstruction(SpvOpStore, id, value, out);
}
}
case Statement::kReturn_Kind:
this->writeReturnStatement((ReturnStatement&) s, out);
break;
- case Statement::kVarDeclaration_Kind:
- this->writeVarDeclaration(*((VarDeclarationStatement&) s).fDeclaration, out);
+ case Statement::kVarDeclarations_Kind:
+ this->writeVarDeclarations(*((VarDeclarationsStatement&) s).fDeclaration, out);
break;
case Statement::kIf_Kind:
this->writeIfStatement((IfStatement&) s, out);
}
for (size_t i = 0; i < program.fElements.size(); i++) {
if (program.fElements[i]->fKind == ProgramElement::kVar_Kind) {
- this->writeGlobalVars(((VarDeclaration&) *program.fElements[i]), body);
+ this->writeGlobalVars(((VarDeclarations&) *program.fElements[i]), body);
}
}
for (size_t i = 0; i < program.fElements.size(); i++) {
SpvId writeFunction(const FunctionDefinition& f, std::ostream& out);
- void writeGlobalVars(const VarDeclaration& v, std::ostream& out);
+ void writeGlobalVars(const VarDeclarations& v, std::ostream& out);
- void writeVarDeclaration(const VarDeclaration& decl, std::ostream& out);
+ void writeVarDeclarations(const VarDeclarations& decl, std::ostream& out);
SpvId writeVariableReference(const VariableReference& ref, std::ostream& out);
ASTModifiers modifiers,
std::string interfaceName,
std::string valueName,
- std::vector<std::unique_ptr<ASTVarDeclaration>> declarations)
+ std::vector<std::unique_ptr<ASTVarDeclarations>> declarations)
: INHERITED(position, kInterfaceBlock_Kind)
, fModifiers(modifiers)
, fInterfaceName(std::move(interfaceName))
const ASTModifiers fModifiers;
const std::string fInterfaceName;
const std::string fValueName;
- const std::vector<std::unique_ptr<ASTVarDeclaration>> fDeclarations;
+ const std::vector<std::unique_ptr<ASTVarDeclarations>> fDeclarations;
typedef ASTDeclaration INHERITED;
};
* found in the LICENSE file.
*/
-#ifndef SKSL_ASTVARDECLARATION
-#define SKSL_ASTVARDECLARATION
+#ifndef SKSL_ASTVARDECLARATIONS
+#define SKSL_ASTVARDECLARATIONS
#include "SkSLASTDeclaration.h"
#include "SkSLASTModifiers.h"
namespace SkSL {
/**
- * A variable declaration, which may consist of multiple individual variables. For instance
- * 'int x, y = 1, z[4][2]' is a single ASTVarDeclaration. This declaration would have a type of
- * 'int', names ['x', 'y', 'z'], sizes of [[], [], [4, 2]], and values of [null, 1, null].
+ * A single variable declaration within a var declaration statement. For instance, the statement
+ * 'int x = 2, y[3];' is an ASTVarDeclarations statement containing two individual ASTVarDeclaration
+ * instances.
*/
-struct ASTVarDeclaration : public ASTDeclaration {
- ASTVarDeclaration(ASTModifiers modifiers,
- std::unique_ptr<ASTType> type,
- std::vector<std::string> names,
- std::vector<std::vector<std::unique_ptr<ASTExpression>>> sizes,
- std::vector<std::unique_ptr<ASTExpression>> values)
+struct ASTVarDeclaration {
+ ASTVarDeclaration(const std::string name,
+ std::vector<std::unique_ptr<ASTExpression>> sizes,
+ std::unique_ptr<ASTExpression> value)
+ : fName(name)
+ , fSizes(std::move(sizes))
+ , fValue(std::move(value)) {}
+
+ std::string description() const {
+ std::string result = fName;
+ for (const auto& size : fSizes) {
+ if (size) {
+ result += "[" + size->description() + "]";
+ } else {
+ result += "[]";
+ }
+ }
+ if (fValue) {
+ result += " = " + fValue->description();
+ }
+ return result;
+ }
+
+ const std::string fName;
+
+ // array sizes, if any. e.g. 'foo[3][]' has sizes [3, null]
+ std::vector<std::unique_ptr<ASTExpression>> fSizes;
+
+ // initial value, may be null
+ std::unique_ptr<ASTExpression> fValue;
+};
+
+/**
+ * A variable declaration statement, which may consist of one or more individual variables.
+ */
+struct ASTVarDeclarations : public ASTDeclaration {
+ ASTVarDeclarations(ASTModifiers modifiers,
+ std::unique_ptr<ASTType> type,
+ std::vector<ASTVarDeclaration> vars)
: INHERITED(type->fPosition, kVar_Kind)
, fModifiers(modifiers)
, fType(std::move(type))
- , fNames(std::move(names))
- , fSizes(std::move(sizes))
- , fValues(std::move(values)) {
- ASSERT(fNames.size() == fValues.size());
- }
+ , fVars(std::move(vars)) {}
std::string description() const override {
std::string result = fModifiers.description() + fType->description() + " ";
std::string separator = "";
- for (size_t i = 0; i < fNames.size(); i++) {
+ for (const auto& var : fVars) {
result += separator;
separator = ", ";
- result += fNames[i];
- for (size_t j = 0; j < fSizes[i].size(); j++) {
- if (fSizes[i][j]) {
- result += "[" + fSizes[i][j]->description() + "]";
- } else {
- result += "[]";
- }
- }
- if (fValues[i]) {
- result += " = " + fValues[i]->description();
- }
+ result += var.description();
}
- return result;
+ return result;
}
const ASTModifiers fModifiers;
const std::unique_ptr<ASTType> fType;
- const std::vector<std::string> fNames;
- const std::vector<std::vector<std::unique_ptr<ASTExpression>>> fSizes;
- const std::vector<std::unique_ptr<ASTExpression>> fValues;
+ const std::vector<ASTVarDeclaration> fVars;
typedef ASTDeclaration INHERITED;
};
* A variable declaration appearing as a statement within a function.
*/
struct ASTVarDeclarationStatement : public ASTStatement {
- ASTVarDeclarationStatement(std::unique_ptr<ASTVarDeclaration> decl)
+ ASTVarDeclarationStatement(std::unique_ptr<ASTVarDeclarations> decl)
: INHERITED(decl->fPosition, kVarDeclaration_Kind)
- , fDeclaration(std::move(decl)) {}
+ , fDeclarations(std::move(decl)) {}
std::string description() const override {
- return fDeclaration->description() + ";";
+ return fDeclarations->description() + ";";
}
- std::unique_ptr<ASTVarDeclaration> fDeclaration;
+ std::unique_ptr<ASTVarDeclarations> fDeclarations;
typedef ASTStatement INHERITED;
};
kFor_Kind,
kIf_Kind,
kReturn_Kind,
- kVarDeclaration_Kind,
+ kVarDeclarations_Kind,
kWhile_Kind
};
* found in the LICENSE file.
*/
-#ifndef SKSL_VARDECLARATION
-#define SKSL_VARDECLARATION
+#ifndef SKSL_VARDECLARATIONS
+#define SKSL_VARDECLARATIONS
#include "SkSLExpression.h"
#include "SkSLStatement.h"
namespace SkSL {
/**
- * A variable declaration, which may consist of multiple individual variables. For instance
- * 'int x, y = 1, z[4][2];' is a single VarDeclaration. This declaration would have a base type of
- * 'int', names ['x', 'y', 'z'], sizes of [[], [], [4, 2]], and values of [null, 1, null].
+ * 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 ProgramElement {
- VarDeclaration(Position position, const Type* baseType, std::vector<const Variable*> vars,
- std::vector<std::vector<std::unique_ptr<Expression>>> sizes,
- std::vector<std::unique_ptr<Expression>> values)
+struct VarDeclaration {
+ VarDeclaration(const Variable* var,
+ std::vector<std::unique_ptr<Expression>> sizes,
+ std::unique_ptr<Expression> value)
+ : fVar(var)
+ , fSizes(std::move(sizes))
+ , fValue(std::move(value)) {}
+
+ std::string description() const {
+ std::string result = 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;
+};
+
+/**
+ * A variable declaration statement, which may consist of one or more individual variables.
+ */
+struct VarDeclarations : public ProgramElement {
+ VarDeclarations(Position position, const Type* baseType,
+ std::vector<VarDeclaration> vars)
: INHERITED(position, kVar_Kind)
, fBaseType(*baseType)
- , fVars(std::move(vars))
- , fSizes(std::move(sizes))
- , fValues(std::move(values)) {}
+ , fVars(std::move(vars)) {}
std::string description() const override {
- std::string result = fVars[0]->fModifiers.description();
- const Type* baseType = &fVars[0]->fType;
- while (baseType->kind() == Type::kArray_Kind) {
- baseType = &baseType->componentType();
+ if (!fVars.size()) {
+ return "";
}
- result += baseType->description();
- std::string separator = " ";
- for (size_t i = 0; i < fVars.size(); i++) {
+ std::string result = fVars[0].fVar->fModifiers.description() + fBaseType.description() +
+ " ";
+ std::string separator = "";
+ for (const auto& var : fVars) {
result += separator;
separator = ", ";
- result += fVars[i]->fName;
- for (size_t j = 0; j < fSizes[i].size(); j++) {
- if (fSizes[i][j]) {
- result += "[" + fSizes[i][j]->description() + "]";
- } else {
- result += "[]";
- }
- }
- if (fValues[i]) {
- result += " = " + fValues[i]->description();
- }
+ result += var.description();
}
- result += ";";
return result;
}
const Type& fBaseType;
- const std::vector<const Variable*> fVars;
- const std::vector<std::vector<std::unique_ptr<Expression>>> fSizes;
- const std::vector<std::unique_ptr<Expression>> fValues;
+ const std::vector<VarDeclaration> fVars;
typedef ProgramElement INHERITED;
};
namespace SkSL {
/**
- * A variable declaration appearing as a statement within a function.
+ * One or more variable declarations appearing as a statement within a function.
*/
-struct VarDeclarationStatement : public Statement {
- VarDeclarationStatement(std::unique_ptr<VarDeclaration> decl)
- : INHERITED(decl->fPosition, kVarDeclaration_Kind)
+struct VarDeclarationsStatement : public Statement {
+ VarDeclarationsStatement(std::unique_ptr<VarDeclarations> decl)
+ : INHERITED(decl->fPosition, kVarDeclarations_Kind)
, fDeclaration(std::move(decl)) {}
std::string description() const override {
return fDeclaration->description();
}
- const std::shared_ptr<VarDeclaration> fDeclaration;
+ const std::shared_ptr<VarDeclarations> fDeclaration;
typedef Statement INHERITED;
};