From 14fe8cc16d2a98d5a96f818e4d0b7127ecad59e2 Mon Sep 17 00:00:00 2001 From: ethannicholas Date: Wed, 7 Sep 2016 13:37:16 -0700 Subject: [PATCH] refactored SkSL VarDeclaration handling GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2312233002 Review-Url: https://codereview.chromium.org/2312233002 --- src/sksl/SkSLCompiler.cpp | 4 +- src/sksl/SkSLGLSLCodeGenerator.cpp | 27 ++++----- src/sksl/SkSLGLSLCodeGenerator.h | 2 +- src/sksl/SkSLIRGenerator.cpp | 71 +++++++++++------------ src/sksl/SkSLIRGenerator.h | 4 +- src/sksl/SkSLParser.cpp | 78 +++++++++++-------------- src/sksl/SkSLParser.h | 12 ++-- src/sksl/SkSLSPIRVCodeGenerator.cpp | 57 ++++++++++--------- src/sksl/SkSLSPIRVCodeGenerator.h | 4 +- src/sksl/ast/SkSLASTInterfaceBlock.h | 4 +- src/sksl/ast/SkSLASTVarDeclaration.h | 81 +++++++++++++++----------- src/sksl/ast/SkSLASTVarDeclarationStatement.h | 8 +-- src/sksl/ir/SkSLStatement.h | 2 +- src/sksl/ir/SkSLVarDeclaration.h | 82 ++++++++++++++++----------- src/sksl/ir/SkSLVarDeclarationStatement.h | 10 ++-- 15 files changed, 232 insertions(+), 214 deletions(-) diff --git a/src/sksl/SkSLCompiler.cpp b/src/sksl/SkSLCompiler.cpp index f55150c..d2ad812 100644 --- a/src/sksl/SkSLCompiler.cpp +++ b/src/sksl/SkSLCompiler.cpp @@ -148,8 +148,8 @@ void Compiler::internalConvertProgram(std::string text, ASTDeclaration& decl = *parsed[i]; switch (decl.fKind) { case ASTDeclaration::kVar_Kind: { - std::unique_ptr s = fIRGenerator->convertVarDeclaration( - (ASTVarDeclaration&) decl, + std::unique_ptr s = fIRGenerator->convertVarDeclarations( + (ASTVarDeclarations&) decl, Variable::kGlobal_Storage); if (s) { result->push_back(std::move(s)); diff --git a/src/sksl/SkSLGLSLCodeGenerator.cpp b/src/sksl/SkSLGLSLCodeGenerator.cpp index 20a39cf..da0bcb9 100644 --- a/src/sksl/SkSLGLSLCodeGenerator.cpp +++ b/src/sksl/SkSLGLSLCodeGenerator.cpp @@ -313,24 +313,24 @@ void GLSLCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) { 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(";"); @@ -348,8 +348,8 @@ void GLSLCodeGenerator::writeStatement(const Statement& s) { 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); @@ -455,9 +455,10 @@ void GLSLCodeGenerator::generateCode(const Program& program, std::ostream& out) 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; diff --git a/src/sksl/SkSLGLSLCodeGenerator.h b/src/sksl/SkSLGLSLCodeGenerator.h index 76512e0..3534aff 100644 --- a/src/sksl/SkSLGLSLCodeGenerator.h +++ b/src/sksl/SkSLGLSLCodeGenerator.h @@ -115,7 +115,7 @@ private: void writeGlobalVars(const VarDeclaration& vs); - void writeVarDeclaration(const VarDeclaration& decl); + void writeVarDeclarations(const VarDeclarations& decl); void writeVariableReference(const VariableReference& ref); diff --git a/src/sksl/SkSLIRGenerator.cpp b/src/sksl/SkSLIRGenerator.cpp index 9b0271b..c30cac1 100644 --- a/src/sksl/SkSLIRGenerator.cpp +++ b/src/sksl/SkSLIRGenerator.cpp @@ -129,35 +129,32 @@ std::unique_ptr IRGenerator::convertBlock(const ASTBlock& block) { std::unique_ptr 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(new VarDeclarationStatement(std::move(decl))); + return std::unique_ptr(new VarDeclarationsStatement(std::move(decl))); } Modifiers IRGenerator::convertModifiers(const ASTModifiers& modifiers) { return Modifiers(modifiers); } -std::unique_ptr IRGenerator::convertVarDeclaration(const ASTVarDeclaration& decl, - Variable::Storage storage) { - std::vector variables; - std::vector>> sizes; - std::vector> values; +std::unique_ptr IRGenerator::convertVarDeclarations(const ASTVarDeclarations& decl, + Variable::Storage storage) { + std::vector 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> 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> sizes; + for (const auto& rawSize : varDecl.fSizes) { + if (rawSize) { + auto size = this->coerce(this->convertExpression(*rawSize), *fContext.fInt_Type); if (!size) { return nullptr; } @@ -175,39 +172,35 @@ std::unique_ptr IRGenerator::convertVarDeclaration(const ASTVarD } 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(new Variable(decl.fPosition, modifiers, decl.fNames[i], + auto var = std::unique_ptr(new Variable(decl.fPosition, modifiers, varDecl.fName, *type, storage)); std::unique_ptr 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(new VarDeclaration(decl.fPosition, - baseType, - std::move(variables), - std::move(sizes), - std::move(values))); + return std::unique_ptr(new VarDeclarations(decl.fPosition, + baseType, + std::move(variables))); } std::unique_ptr IRGenerator::convertIf(const ASTIfStatement& s) { @@ -482,21 +475,21 @@ std::unique_ptr IRGenerator::convertInterfaceBlock(const ASTInte Modifiers mods = this->convertModifiers(intf.fModifiers); std::vector fields; for (size_t i = 0; i < intf.fDeclarations.size(); i++) { - std::unique_ptr decl = this->convertVarDeclaration( + std::unique_ptr 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"); } } diff --git a/src/sksl/SkSLIRGenerator.h b/src/sksl/SkSLIRGenerator.h index 2384b2d..a3ff210 100644 --- a/src/sksl/SkSLIRGenerator.h +++ b/src/sksl/SkSLIRGenerator.h @@ -56,8 +56,8 @@ public: IRGenerator(const Context* context, std::shared_ptr root, ErrorReporter& errorReporter); - std::unique_ptr convertVarDeclaration(const ASTVarDeclaration& decl, - Variable::Storage storage); + std::unique_ptr convertVarDeclarations(const ASTVarDeclarations& decl, + Variable::Storage storage); std::unique_ptr convertFunction(const ASTFunction& f); std::unique_ptr convertStatement(const ASTStatement& statement); std::unique_ptr convertExpression(const ASTExpression& expression); diff --git a/src/sksl/SkSLParser.cpp b/src/sksl/SkSLParser.cpp index 65187c3..b240e45 100644 --- a/src/sksl/SkSLParser.cpp +++ b/src/sksl/SkSLParser.cpp @@ -274,7 +274,7 @@ std::unique_ptr Parser::declaration() { } /* modifiers type IDENTIFIER varDeclarationEnd */ -std::unique_ptr Parser::varDeclaration() { +std::unique_ptr Parser::varDeclarations() { ASTModifiers modifiers = this->modifiers(); std::unique_ptr type(this->type()); if (!type) { @@ -301,23 +301,23 @@ std::unique_ptr Parser::structDeclaration() { } std::vector fields; while (this->peek().fKind != Token::RBRACE) { - std::unique_ptr decl = this->varDeclaration(); + std::unique_ptr 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"); } } @@ -331,20 +331,20 @@ std::unique_ptr Parser::structDeclaration() { } /* structDeclaration ((IDENTIFIER varDeclarationEnd) | SEMICOLON) */ -std::unique_ptr Parser::structVarDeclaration(ASTModifiers modifiers) { +std::unique_ptr Parser::structVarDeclaration(ASTModifiers modifiers) { std::unique_ptr type = this->structDeclaration(); if (!type) { return nullptr; } if (peek().fKind == Token::IDENTIFIER) { Token name = this->nextToken(); - std::unique_ptr result = this->varDeclarationEnd(modifiers, - std::move(type), - std::move(name.fText)); + std::unique_ptr 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"); } } @@ -357,12 +357,10 @@ std::unique_ptr Parser::structVarDeclaration(ASTModifiers mod /* (LBRACKET expression? RBRACKET)* (EQ expression)? (COMMA IDENTIFER (LBRACKET expression? RBRACKET)* (EQ expression)?)* SEMICOLON */ -std::unique_ptr Parser::varDeclarationEnd(ASTModifiers mods, - std::unique_ptr type, - std::string name) { - std::vector names; - std::vector>> sizes; - names.push_back(name); +std::unique_ptr Parser::varDeclarationEnd(ASTModifiers mods, + std::unique_ptr type, + std::string name) { + std::vector vars; std::vector> currentVarSizes; while (this->peek().fKind == Token::LBRACKET) { this->nextToken(); @@ -380,26 +378,23 @@ std::unique_ptr Parser::varDeclarationEnd(ASTModifiers mods, } } } - sizes.push_back(std::move(currentVarSizes)); - std::vector> values; + std::unique_ptr value; if (this->peek().fKind == Token::EQ) { this->nextToken(); - std::unique_ptr 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) { @@ -416,26 +411,21 @@ std::unique_ptr Parser::varDeclarationEnd(ASTModifiers mods, } } } - sizes.push_back(std::move(currentVarSizes)); if (this->peek().fKind == Token::EQ) { this->nextToken(); - std::unique_ptr 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(new ASTVarDeclaration(std::move(mods), - std::move(type), - std::move(names), - std::move(sizes), - std::move(values))); + return std::unique_ptr(new ASTVarDeclarations(std::move(mods), + std::move(type), + std::move(vars))); } /* modifiers type IDENTIFIER (LBRACKET INT_LITERAL RBRACKET)? */ @@ -614,7 +604,7 @@ std::unique_ptr Parser::statement() { 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; } @@ -622,7 +612,7 @@ std::unique_ptr Parser::statement() { } case Token::IDENTIFIER: if (this->isType(start.fText)) { - auto decl = this->varDeclaration(); + auto decl = this->varDeclarations(); if (!decl) { return nullptr; } @@ -663,9 +653,9 @@ std::unique_ptr Parser::interfaceBlock(ASTModifiers mods) { return nullptr; } this->nextToken(); - std::vector> decls; + std::vector> decls; while (this->peek().fKind != Token::RBRACE) { - std::unique_ptr decl = this->varDeclaration(); + std::unique_ptr decl = this->varDeclarations(); if (!decl) { return nullptr; } @@ -788,12 +778,12 @@ std::unique_ptr Parser::forStatement() { break; case Token::CONST: initializer = std::unique_ptr(new ASTVarDeclarationStatement( - this->varDeclaration())); + this->varDeclarations())); break; case Token::IDENTIFIER: if (this->isType(nextToken.fText)) { initializer = std::unique_ptr(new ASTVarDeclarationStatement( - this->varDeclaration())); + this->varDeclarations())); break; } // fall through diff --git a/src/sksl/SkSLParser.h b/src/sksl/SkSLParser.h index 45629a3..75f304b 100644 --- a/src/sksl/SkSLParser.h +++ b/src/sksl/SkSLParser.h @@ -40,7 +40,7 @@ struct ASTStatement; struct ASTSuffix; struct ASTType; struct ASTWhileStatement; -struct ASTVarDeclaration; +struct ASTVarDeclarations; class SymbolTable; /** @@ -106,15 +106,15 @@ private: std::unique_ptr declaration(); - std::unique_ptr varDeclaration(); + std::unique_ptr varDeclarations(); std::unique_ptr structDeclaration(); - std::unique_ptr structVarDeclaration(ASTModifiers modifiers); + std::unique_ptr structVarDeclaration(ASTModifiers modifiers); - std::unique_ptr varDeclarationEnd(ASTModifiers modifiers, - std::unique_ptr type, - std::string name); + std::unique_ptr varDeclarationEnd(ASTModifiers modifiers, + std::unique_ptr type, + std::string name); std::unique_ptr parameter(); diff --git a/src/sksl/SkSLSPIRVCodeGenerator.cpp b/src/sksl/SkSLSPIRVCodeGenerator.cpp index efa41bf..d17e3c4 100644 --- a/src/sksl/SkSLSPIRVCodeGenerator.cpp +++ b/src/sksl/SkSLSPIRVCodeGenerator.cpp @@ -2363,23 +2363,25 @@ SpvId SPIRVCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) { 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; @@ -2388,36 +2390,37 @@ void SPIRVCodeGenerator::writeGlobalVars(const VarDeclaration& decl, std::ostrea 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); } } @@ -2434,8 +2437,8 @@ void SPIRVCodeGenerator::writeStatement(const Statement& s, std::ostream& 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); @@ -2559,7 +2562,7 @@ void SPIRVCodeGenerator::writeInstructions(const Program& program, std::ostream& } 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++) { diff --git a/src/sksl/SkSLSPIRVCodeGenerator.h b/src/sksl/SkSLSPIRVCodeGenerator.h index caae201..e7b2b30 100644 --- a/src/sksl/SkSLSPIRVCodeGenerator.h +++ b/src/sksl/SkSLSPIRVCodeGenerator.h @@ -115,9 +115,9 @@ private: 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); diff --git a/src/sksl/ast/SkSLASTInterfaceBlock.h b/src/sksl/ast/SkSLASTInterfaceBlock.h index f501b12..c271362 100644 --- a/src/sksl/ast/SkSLASTInterfaceBlock.h +++ b/src/sksl/ast/SkSLASTInterfaceBlock.h @@ -26,7 +26,7 @@ struct ASTInterfaceBlock : public ASTDeclaration { ASTModifiers modifiers, std::string interfaceName, std::string valueName, - std::vector> declarations) + std::vector> declarations) : INHERITED(position, kInterfaceBlock_Kind) , fModifiers(modifiers) , fInterfaceName(std::move(interfaceName)) @@ -48,7 +48,7 @@ struct ASTInterfaceBlock : public ASTDeclaration { const ASTModifiers fModifiers; const std::string fInterfaceName; const std::string fValueName; - const std::vector> fDeclarations; + const std::vector> fDeclarations; typedef ASTDeclaration INHERITED; }; diff --git a/src/sksl/ast/SkSLASTVarDeclaration.h b/src/sksl/ast/SkSLASTVarDeclaration.h index 613867e..2eaf498 100644 --- a/src/sksl/ast/SkSLASTVarDeclaration.h +++ b/src/sksl/ast/SkSLASTVarDeclaration.h @@ -5,8 +5,8 @@ * found in the LICENSE file. */ -#ifndef SKSL_ASTVARDECLARATION -#define SKSL_ASTVARDECLARATION +#ifndef SKSL_ASTVARDECLARATIONS +#define SKSL_ASTVARDECLARATIONS #include "SkSLASTDeclaration.h" #include "SkSLASTModifiers.h" @@ -17,51 +17,68 @@ 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 type, - std::vector names, - std::vector>> sizes, - std::vector> values) +struct ASTVarDeclaration { + ASTVarDeclaration(const std::string name, + std::vector> sizes, + std::unique_ptr 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> fSizes; + + // initial value, may be null + std::unique_ptr fValue; +}; + +/** + * A variable declaration statement, which may consist of one or more individual variables. + */ +struct ASTVarDeclarations : public ASTDeclaration { + ASTVarDeclarations(ASTModifiers modifiers, + std::unique_ptr type, + std::vector 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 fType; - const std::vector fNames; - const std::vector>> fSizes; - const std::vector> fValues; + const std::vector fVars; typedef ASTDeclaration INHERITED; }; diff --git a/src/sksl/ast/SkSLASTVarDeclarationStatement.h b/src/sksl/ast/SkSLASTVarDeclarationStatement.h index b647b6e..8bae389 100644 --- a/src/sksl/ast/SkSLASTVarDeclarationStatement.h +++ b/src/sksl/ast/SkSLASTVarDeclarationStatement.h @@ -17,15 +17,15 @@ namespace SkSL { * A variable declaration appearing as a statement within a function. */ struct ASTVarDeclarationStatement : public ASTStatement { - ASTVarDeclarationStatement(std::unique_ptr decl) + ASTVarDeclarationStatement(std::unique_ptr 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 fDeclaration; + std::unique_ptr fDeclarations; typedef ASTStatement INHERITED; }; diff --git a/src/sksl/ir/SkSLStatement.h b/src/sksl/ir/SkSLStatement.h index 64b7bdf..012311f 100644 --- a/src/sksl/ir/SkSLStatement.h +++ b/src/sksl/ir/SkSLStatement.h @@ -27,7 +27,7 @@ struct Statement : public IRNode { kFor_Kind, kIf_Kind, kReturn_Kind, - kVarDeclaration_Kind, + kVarDeclarations_Kind, kWhile_Kind }; diff --git a/src/sksl/ir/SkSLVarDeclaration.h b/src/sksl/ir/SkSLVarDeclaration.h index ca3c7f9..e64a874 100644 --- a/src/sksl/ir/SkSLVarDeclaration.h +++ b/src/sksl/ir/SkSLVarDeclaration.h @@ -5,8 +5,8 @@ * found in the LICENSE file. */ -#ifndef SKSL_VARDECLARATION -#define SKSL_VARDECLARATION +#ifndef SKSL_VARDECLARATIONS +#define SKSL_VARDECLARATIONS #include "SkSLExpression.h" #include "SkSLStatement.h" @@ -15,51 +15,65 @@ 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 vars, - std::vector>> sizes, - std::vector> values) +struct VarDeclaration { + VarDeclaration(const Variable* var, + std::vector> sizes, + std::unique_ptr 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> fSizes; + std::unique_ptr 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 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 fVars; - const std::vector>> fSizes; - const std::vector> fValues; + const std::vector fVars; typedef ProgramElement INHERITED; }; diff --git a/src/sksl/ir/SkSLVarDeclarationStatement.h b/src/sksl/ir/SkSLVarDeclarationStatement.h index e81c0ac..59d37ab 100644 --- a/src/sksl/ir/SkSLVarDeclarationStatement.h +++ b/src/sksl/ir/SkSLVarDeclarationStatement.h @@ -14,18 +14,18 @@ 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 decl) - : INHERITED(decl->fPosition, kVarDeclaration_Kind) +struct VarDeclarationsStatement : public Statement { + VarDeclarationsStatement(std::unique_ptr decl) + : INHERITED(decl->fPosition, kVarDeclarations_Kind) , fDeclaration(std::move(decl)) {} std::string description() const override { return fDeclaration->description(); } - const std::shared_ptr fDeclaration; + const std::shared_ptr fDeclaration; typedef Statement INHERITED; }; -- 2.7.4