refactored SkSL VarDeclaration handling

GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2312233002

Review-Url: https://codereview.chromium.org/2312233002
This commit is contained in:
ethannicholas 2016-09-07 13:37:16 -07:00 committed by Commit bot
parent ef6a9b7f93
commit 14fe8cc16d
15 changed files with 237 additions and 219 deletions

View File

@ -148,8 +148,8 @@ void Compiler::internalConvertProgram(std::string text,
ASTDeclaration& decl = *parsed[i]; ASTDeclaration& decl = *parsed[i];
switch (decl.fKind) { switch (decl.fKind) {
case ASTDeclaration::kVar_Kind: { case ASTDeclaration::kVar_Kind: {
std::unique_ptr<VarDeclaration> s = fIRGenerator->convertVarDeclaration( std::unique_ptr<VarDeclarations> s = fIRGenerator->convertVarDeclarations(
(ASTVarDeclaration&) decl, (ASTVarDeclarations&) decl,
Variable::kGlobal_Storage); Variable::kGlobal_Storage);
if (s) { if (s) {
result->push_back(std::move(s)); result->push_back(std::move(s));

View File

@ -313,24 +313,24 @@ void GLSLCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) {
this->writeLine("};"); this->writeLine("};");
} }
void GLSLCodeGenerator::writeVarDeclaration(const VarDeclaration& decl) { void GLSLCodeGenerator::writeVarDeclarations(const VarDeclarations& decl) {
ASSERT(decl.fVars.size() > 0); ASSERT(decl.fVars.size() > 0);
this->writeModifiers(decl.fVars[0]->fModifiers); this->writeModifiers(decl.fVars[0].fVar->fModifiers);
this->writeType(decl.fBaseType); this->writeType(decl.fBaseType);
std::string separator = " "; std::string separator = " ";
for (size_t i = 0; i < decl.fVars.size(); i++) { for (const auto& var : decl.fVars) {
ASSERT(decl.fVars[i]->fModifiers == decl.fVars[0]->fModifiers); ASSERT(var.fVar->fModifiers == decl.fVars[0].fVar->fModifiers);
this->write(separator); this->write(separator);
separator = ", "; separator = ", ";
this->write(decl.fVars[i]->fName); this->write(var.fVar->fName);
for (const auto& size : decl.fSizes[i]) { for (const auto& size : var.fSizes) {
this->write("["); this->write("[");
this->writeExpression(*size, kTopLevel_Precedence); this->writeExpression(*size, kTopLevel_Precedence);
this->write("]"); this->write("]");
} }
if (decl.fValues[i]) { if (var.fValue) {
this->write(" = "); this->write(" = ");
this->writeExpression(*decl.fValues[i], kTopLevel_Precedence); this->writeExpression(*var.fValue, kTopLevel_Precedence);
} }
} }
this->write(";"); this->write(";");
@ -348,8 +348,8 @@ void GLSLCodeGenerator::writeStatement(const Statement& s) {
case Statement::kReturn_Kind: case Statement::kReturn_Kind:
this->writeReturnStatement((ReturnStatement&) s); this->writeReturnStatement((ReturnStatement&) s);
break; break;
case Statement::kVarDeclaration_Kind: case Statement::kVarDeclarations_Kind:
this->writeVarDeclaration(*((VarDeclarationStatement&) s).fDeclaration); this->writeVarDeclarations(*((VarDeclarationsStatement&) s).fDeclaration);
break; break;
case Statement::kIf_Kind: case Statement::kIf_Kind:
this->writeIfStatement((IfStatement&) s); this->writeIfStatement((IfStatement&) s);
@ -455,9 +455,10 @@ void GLSLCodeGenerator::generateCode(const Program& program, std::ostream& out)
this->writeExtension((Extension&) *e); this->writeExtension((Extension&) *e);
break; break;
case ProgramElement::kVar_Kind: { case ProgramElement::kVar_Kind: {
VarDeclaration& decl = (VarDeclaration&) *e; VarDeclarations& decl = (VarDeclarations&) *e;
if (decl.fVars.size() > 0 && decl.fVars[0]->fModifiers.fLayout.fBuiltin == -1) { if (decl.fVars.size() > 0 &&
this->writeVarDeclaration(decl); decl.fVars[0].fVar->fModifiers.fLayout.fBuiltin == -1) {
this->writeVarDeclarations(decl);
this->writeLine(); this->writeLine();
} }
break; break;

View File

@ -115,7 +115,7 @@ private:
void writeGlobalVars(const VarDeclaration& vs); void writeGlobalVars(const VarDeclaration& vs);
void writeVarDeclaration(const VarDeclaration& decl); void writeVarDeclarations(const VarDeclarations& decl);
void writeVariableReference(const VariableReference& ref); void writeVariableReference(const VariableReference& ref);

View File

@ -129,35 +129,32 @@ std::unique_ptr<Block> IRGenerator::convertBlock(const ASTBlock& block) {
std::unique_ptr<Statement> IRGenerator::convertVarDeclarationStatement( std::unique_ptr<Statement> IRGenerator::convertVarDeclarationStatement(
const ASTVarDeclarationStatement& s) { const ASTVarDeclarationStatement& s) {
auto decl = this->convertVarDeclaration(*s.fDeclaration, Variable::kLocal_Storage); auto decl = this->convertVarDeclarations(*s.fDeclarations, Variable::kLocal_Storage);
if (!decl) { if (!decl) {
return nullptr; 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) { Modifiers IRGenerator::convertModifiers(const ASTModifiers& modifiers) {
return Modifiers(modifiers); return Modifiers(modifiers);
} }
std::unique_ptr<VarDeclaration> IRGenerator::convertVarDeclaration(const ASTVarDeclaration& decl, std::unique_ptr<VarDeclarations> IRGenerator::convertVarDeclarations(const ASTVarDeclarations& decl,
Variable::Storage storage) { Variable::Storage storage) {
std::vector<const Variable*> variables; std::vector<VarDeclaration> variables;
std::vector<std::vector<std::unique_ptr<Expression>>> sizes;
std::vector<std::unique_ptr<Expression>> values;
const Type* baseType = this->convertType(*decl.fType); const Type* baseType = this->convertType(*decl.fType);
if (!baseType) { if (!baseType) {
return nullptr; return nullptr;
} }
for (size_t i = 0; i < decl.fNames.size(); i++) { for (const auto& varDecl : decl.fVars) {
Modifiers modifiers = this->convertModifiers(decl.fModifiers); Modifiers modifiers = this->convertModifiers(decl.fModifiers);
const Type* type = baseType; const Type* type = baseType;
ASSERT(type->kind() != Type::kArray_Kind); ASSERT(type->kind() != Type::kArray_Kind);
std::vector<std::unique_ptr<Expression>> currentVarSizes; std::vector<std::unique_ptr<Expression>> sizes;
for (size_t j = 0; j < decl.fSizes[i].size(); j++) { for (const auto& rawSize : varDecl.fSizes) {
if (decl.fSizes[i][j]) { if (rawSize) {
ASTExpression& rawSize = *decl.fSizes[i][j]; auto size = this->coerce(this->convertExpression(*rawSize), *fContext.fInt_Type);
auto size = this->coerce(this->convertExpression(rawSize), *fContext.fInt_Type);
if (!size) { if (!size) {
return nullptr; return nullptr;
} }
@ -175,39 +172,35 @@ std::unique_ptr<VarDeclaration> IRGenerator::convertVarDeclaration(const ASTVarD
} }
type = new Type(name, Type::kArray_Kind, *type, (int) count); type = new Type(name, Type::kArray_Kind, *type, (int) count);
fSymbolTable->takeOwnership((Type*) type); fSymbolTable->takeOwnership((Type*) type);
currentVarSizes.push_back(std::move(size)); sizes.push_back(std::move(size));
} else { } else {
type = new Type(type->fName + "[]", Type::kArray_Kind, *type, -1); type = new Type(type->fName + "[]", Type::kArray_Kind, *type, -1);
fSymbolTable->takeOwnership((Type*) type); 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)); *type, storage));
std::unique_ptr<Expression> value; std::unique_ptr<Expression> value;
if (decl.fValues[i]) { if (varDecl.fValue) {
value = this->convertExpression(*decl.fValues[i]); value = this->convertExpression(*varDecl.fValue);
if (!value) { if (!value) {
return nullptr; return nullptr;
} }
value = this->coerce(std::move(value), *type); 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 // already defined, just update the modifiers
Variable* old = (Variable*) (*fSymbolTable)[decl.fNames[i]]; Variable* old = (Variable*) (*fSymbolTable)[varDecl.fName];
old->fModifiers = var->fModifiers; old->fModifiers = var->fModifiers;
} else { } else {
variables.push_back(var.get()); variables.emplace_back(var.get(), std::move(sizes), std::move(value));
fSymbolTable->add(decl.fNames[i], std::move(var)); fSymbolTable->add(varDecl.fName, std::move(var));
values.push_back(std::move(value));
sizes.push_back(std::move(currentVarSizes));
} }
} }
return std::unique_ptr<VarDeclaration>(new VarDeclaration(decl.fPosition, return std::unique_ptr<VarDeclarations>(new VarDeclarations(decl.fPosition,
baseType, baseType,
std::move(variables), std::move(variables)));
std::move(sizes),
std::move(values)));
} }
std::unique_ptr<Statement> IRGenerator::convertIf(const ASTIfStatement& s) { std::unique_ptr<Statement> IRGenerator::convertIf(const ASTIfStatement& s) {
@ -482,21 +475,21 @@ std::unique_ptr<InterfaceBlock> IRGenerator::convertInterfaceBlock(const ASTInte
Modifiers mods = this->convertModifiers(intf.fModifiers); Modifiers mods = this->convertModifiers(intf.fModifiers);
std::vector<Type::Field> fields; std::vector<Type::Field> fields;
for (size_t i = 0; i < intf.fDeclarations.size(); i++) { 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], *intf.fDeclarations[i],
Variable::kGlobal_Storage); Variable::kGlobal_Storage);
for (size_t j = 0; j < decl->fVars.size(); j++) { for (const auto& var : decl->fVars) {
fields.push_back(Type::Field(decl->fVars[j]->fModifiers, decl->fVars[j]->fName, fields.push_back(Type::Field(var.fVar->fModifiers, var.fVar->fName,
&decl->fVars[j]->fType)); &var.fVar->fType));
if (decl->fValues[j]) { if (var.fValue) {
fErrors.error(decl->fPosition, fErrors.error(decl->fPosition,
"initializers are not permitted on interface block fields"); "initializers are not permitted on interface block fields");
} }
if (decl->fVars[j]->fModifiers.fFlags & (Modifiers::kIn_Flag | if (var.fVar->fModifiers.fFlags & (Modifiers::kIn_Flag |
Modifiers::kOut_Flag | Modifiers::kOut_Flag |
Modifiers::kUniform_Flag | Modifiers::kUniform_Flag |
Modifiers::kConst_Flag)) { Modifiers::kConst_Flag)) {
fErrors.error(decl->fPosition, fErrors.error(decl->fPosition,
"interface block fields may not have storage qualifiers"); "interface block fields may not have storage qualifiers");
} }
} }

View File

@ -56,8 +56,8 @@ public:
IRGenerator(const Context* context, std::shared_ptr<SymbolTable> root, IRGenerator(const Context* context, std::shared_ptr<SymbolTable> root,
ErrorReporter& errorReporter); ErrorReporter& errorReporter);
std::unique_ptr<VarDeclaration> convertVarDeclaration(const ASTVarDeclaration& decl, std::unique_ptr<VarDeclarations> convertVarDeclarations(const ASTVarDeclarations& decl,
Variable::Storage storage); Variable::Storage storage);
std::unique_ptr<FunctionDefinition> convertFunction(const ASTFunction& f); std::unique_ptr<FunctionDefinition> convertFunction(const ASTFunction& f);
std::unique_ptr<Statement> convertStatement(const ASTStatement& statement); std::unique_ptr<Statement> convertStatement(const ASTStatement& statement);
std::unique_ptr<Expression> convertExpression(const ASTExpression& expression); std::unique_ptr<Expression> convertExpression(const ASTExpression& expression);

View File

@ -274,7 +274,7 @@ std::unique_ptr<ASTDeclaration> Parser::declaration() {
} }
/* modifiers type IDENTIFIER varDeclarationEnd */ /* modifiers type IDENTIFIER varDeclarationEnd */
std::unique_ptr<ASTVarDeclaration> Parser::varDeclaration() { std::unique_ptr<ASTVarDeclarations> Parser::varDeclarations() {
ASTModifiers modifiers = this->modifiers(); ASTModifiers modifiers = this->modifiers();
std::unique_ptr<ASTType> type(this->type()); std::unique_ptr<ASTType> type(this->type());
if (!type) { if (!type) {
@ -301,23 +301,23 @@ std::unique_ptr<ASTType> Parser::structDeclaration() {
} }
std::vector<Type::Field> fields; std::vector<Type::Field> fields;
while (this->peek().fKind != Token::RBRACE) { while (this->peek().fKind != Token::RBRACE) {
std::unique_ptr<ASTVarDeclaration> decl = this->varDeclaration(); std::unique_ptr<ASTVarDeclarations> decl = this->varDeclarations();
if (!decl) { if (!decl) {
return nullptr; 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]; auto type = (const Type*) fTypes[decl->fType->fName];
for (int j = (int) decl->fSizes[i].size() - 1; j >= 0; j--) { for (int i = (int) var.fSizes.size() - 1; i >= 0; i--) {
if (decl->fSizes[i][j]->fKind != ASTExpression::kInt_Kind) { if (var.fSizes[i]->fKind != ASTExpression::kInt_Kind) {
this->error(decl->fPosition, "array size in struct field must be a constant"); 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) + "]"; std::string name = type->name() + "[" + to_string(columns) + "]";
type = new Type(name, Type::kArray_Kind, *type, (int) columns); type = new Type(name, Type::kArray_Kind, *type, (int) columns);
fTypes.takeOwnership((Type*) type); fTypes.takeOwnership((Type*) type);
} }
fields.push_back(Type::Field(decl->fModifiers, decl->fNames[i], type)); fields.push_back(Type::Field(decl->fModifiers, var.fName, type));
if (decl->fValues[i]) { if (var.fValue) {
this->error(decl->fPosition, "initializers are not permitted on struct fields"); this->error(decl->fPosition, "initializers are not permitted on struct fields");
} }
} }
@ -331,20 +331,20 @@ std::unique_ptr<ASTType> Parser::structDeclaration() {
} }
/* structDeclaration ((IDENTIFIER varDeclarationEnd) | SEMICOLON) */ /* 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(); std::unique_ptr<ASTType> type = this->structDeclaration();
if (!type) { if (!type) {
return nullptr; return nullptr;
} }
if (peek().fKind == Token::IDENTIFIER) { if (peek().fKind == Token::IDENTIFIER) {
Token name = this->nextToken(); Token name = this->nextToken();
std::unique_ptr<ASTVarDeclaration> result = this->varDeclarationEnd(modifiers, std::unique_ptr<ASTVarDeclarations> result = this->varDeclarationEnd(modifiers,
std::move(type), std::move(type),
std::move(name.fText)); std::move(name.fText));
if (result) { if (result) {
for (size_t i = 0; i < result->fValues.size(); i++) { for (const auto& var : result->fVars) {
if (result->fValues[i]) { if (var.fValue) {
this->error(result->fValues[i]->fPosition, this->error(var.fValue->fPosition,
"struct variables cannot be initialized"); "struct variables cannot be initialized");
} }
} }
@ -357,12 +357,10 @@ std::unique_ptr<ASTVarDeclaration> Parser::structVarDeclaration(ASTModifiers mod
/* (LBRACKET expression? RBRACKET)* (EQ expression)? (COMMA IDENTIFER /* (LBRACKET expression? RBRACKET)* (EQ expression)? (COMMA IDENTIFER
(LBRACKET expression? RBRACKET)* (EQ expression)?)* SEMICOLON */ (LBRACKET expression? RBRACKET)* (EQ expression)?)* SEMICOLON */
std::unique_ptr<ASTVarDeclaration> Parser::varDeclarationEnd(ASTModifiers mods, std::unique_ptr<ASTVarDeclarations> Parser::varDeclarationEnd(ASTModifiers mods,
std::unique_ptr<ASTType> type, std::unique_ptr<ASTType> type,
std::string name) { std::string name) {
std::vector<std::string> names; std::vector<ASTVarDeclaration> vars;
std::vector<std::vector<std::unique_ptr<ASTExpression>>> sizes;
names.push_back(name);
std::vector<std::unique_ptr<ASTExpression>> currentVarSizes; std::vector<std::unique_ptr<ASTExpression>> currentVarSizes;
while (this->peek().fKind == Token::LBRACKET) { while (this->peek().fKind == Token::LBRACKET) {
this->nextToken(); this->nextToken();
@ -380,26 +378,23 @@ std::unique_ptr<ASTVarDeclaration> Parser::varDeclarationEnd(ASTModifiers mods,
} }
} }
} }
sizes.push_back(std::move(currentVarSizes)); std::unique_ptr<ASTExpression> value;
std::vector<std::unique_ptr<ASTExpression>> values;
if (this->peek().fKind == Token::EQ) { if (this->peek().fKind == Token::EQ) {
this->nextToken(); this->nextToken();
std::unique_ptr<ASTExpression> value(this->expression()); value = this->expression();
if (!value) { if (!value) {
return nullptr; 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) { while (this->peek().fKind == Token::COMMA) {
this->nextToken(); this->nextToken();
Token name; Token name;
if (!this->expect(Token::IDENTIFIER, "an identifier", &name)) { if (!this->expect(Token::IDENTIFIER, "an identifier", &name)) {
return nullptr; return nullptr;
} }
names.push_back(name.fText);
currentVarSizes.clear(); currentVarSizes.clear();
value.reset();
while (this->peek().fKind == Token::LBRACKET) { while (this->peek().fKind == Token::LBRACKET) {
this->nextToken(); this->nextToken();
if (this->peek().fKind == Token::RBRACKET) { if (this->peek().fKind == Token::RBRACKET) {
@ -416,26 +411,21 @@ std::unique_ptr<ASTVarDeclaration> Parser::varDeclarationEnd(ASTModifiers mods,
} }
} }
} }
sizes.push_back(std::move(currentVarSizes));
if (this->peek().fKind == Token::EQ) { if (this->peek().fKind == Token::EQ) {
this->nextToken(); this->nextToken();
std::unique_ptr<ASTExpression> value(this->expression()); value = this->expression();
if (!value) { if (!value) {
return nullptr; 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, "';'")) { if (!this->expect(Token::SEMICOLON, "';'")) {
return nullptr; return nullptr;
} }
return std::unique_ptr<ASTVarDeclaration>(new ASTVarDeclaration(std::move(mods), return std::unique_ptr<ASTVarDeclarations>(new ASTVarDeclarations(std::move(mods),
std::move(type), std::move(type),
std::move(names), std::move(vars)));
std::move(sizes),
std::move(values)));
} }
/* modifiers type IDENTIFIER (LBRACKET INT_LITERAL RBRACKET)? */ /* modifiers type IDENTIFIER (LBRACKET INT_LITERAL RBRACKET)? */
@ -614,7 +604,7 @@ std::unique_ptr<ASTStatement> Parser::statement() {
case Token::HIGHP: // fall through case Token::HIGHP: // fall through
case Token::MEDIUMP: // fall through case Token::MEDIUMP: // fall through
case Token::LOWP: { case Token::LOWP: {
auto decl = this->varDeclaration(); auto decl = this->varDeclarations();
if (!decl) { if (!decl) {
return nullptr; return nullptr;
} }
@ -622,7 +612,7 @@ std::unique_ptr<ASTStatement> Parser::statement() {
} }
case Token::IDENTIFIER: case Token::IDENTIFIER:
if (this->isType(start.fText)) { if (this->isType(start.fText)) {
auto decl = this->varDeclaration(); auto decl = this->varDeclarations();
if (!decl) { if (!decl) {
return nullptr; return nullptr;
} }
@ -663,9 +653,9 @@ std::unique_ptr<ASTDeclaration> Parser::interfaceBlock(ASTModifiers mods) {
return nullptr; return nullptr;
} }
this->nextToken(); this->nextToken();
std::vector<std::unique_ptr<ASTVarDeclaration>> decls; std::vector<std::unique_ptr<ASTVarDeclarations>> decls;
while (this->peek().fKind != Token::RBRACE) { while (this->peek().fKind != Token::RBRACE) {
std::unique_ptr<ASTVarDeclaration> decl = this->varDeclaration(); std::unique_ptr<ASTVarDeclarations> decl = this->varDeclarations();
if (!decl) { if (!decl) {
return nullptr; return nullptr;
} }
@ -788,12 +778,12 @@ std::unique_ptr<ASTForStatement> Parser::forStatement() {
break; break;
case Token::CONST: case Token::CONST:
initializer = std::unique_ptr<ASTStatement>(new ASTVarDeclarationStatement( initializer = std::unique_ptr<ASTStatement>(new ASTVarDeclarationStatement(
this->varDeclaration())); this->varDeclarations()));
break; break;
case Token::IDENTIFIER: case Token::IDENTIFIER:
if (this->isType(nextToken.fText)) { if (this->isType(nextToken.fText)) {
initializer = std::unique_ptr<ASTStatement>(new ASTVarDeclarationStatement( initializer = std::unique_ptr<ASTStatement>(new ASTVarDeclarationStatement(
this->varDeclaration())); this->varDeclarations()));
break; break;
} }
// fall through // fall through

View File

@ -40,7 +40,7 @@ struct ASTStatement;
struct ASTSuffix; struct ASTSuffix;
struct ASTType; struct ASTType;
struct ASTWhileStatement; struct ASTWhileStatement;
struct ASTVarDeclaration; struct ASTVarDeclarations;
class SymbolTable; class SymbolTable;
/** /**
@ -106,15 +106,15 @@ private:
std::unique_ptr<ASTDeclaration> declaration(); std::unique_ptr<ASTDeclaration> declaration();
std::unique_ptr<ASTVarDeclaration> varDeclaration(); std::unique_ptr<ASTVarDeclarations> varDeclarations();
std::unique_ptr<ASTType> structDeclaration(); 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<ASTVarDeclarations> varDeclarationEnd(ASTModifiers modifiers,
std::unique_ptr<ASTType> type, std::unique_ptr<ASTType> type,
std::string name); std::string name);
std::unique_ptr<ASTParameter> parameter(); std::unique_ptr<ASTParameter> parameter();

View File

@ -2363,23 +2363,25 @@ SpvId SPIRVCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) {
return result; 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++) { for (size_t i = 0; i < decl.fVars.size(); i++) {
if (!decl.fVars[i]->fIsReadFrom && !decl.fVars[i]->fIsWrittenTo && const VarDeclaration& varDecl = decl.fVars[i];
!(decl.fVars[i]->fModifiers.fFlags & (Modifiers::kIn_Flag | const Variable* var = varDecl.fVar;
Modifiers::kOut_Flag | if (!var->fIsReadFrom && !var->fIsWrittenTo &&
Modifiers::kUniform_Flag))) { !(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 // 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) // we elide an interface var, even if it's dead)
continue; continue;
} }
SpvStorageClass_ storageClass; SpvStorageClass_ storageClass;
if (decl.fVars[i]->fModifiers.fFlags & Modifiers::kIn_Flag) { if (var->fModifiers.fFlags & Modifiers::kIn_Flag) {
storageClass = SpvStorageClassInput; storageClass = SpvStorageClassInput;
} else if (decl.fVars[i]->fModifiers.fFlags & Modifiers::kOut_Flag) { } else if (var->fModifiers.fFlags & Modifiers::kOut_Flag) {
storageClass = SpvStorageClassOutput; storageClass = SpvStorageClassOutput;
} else if (decl.fVars[i]->fModifiers.fFlags & Modifiers::kUniform_Flag) { } else if (var->fModifiers.fFlags & Modifiers::kUniform_Flag) {
if (decl.fVars[i]->fType.kind() == Type::kSampler_Kind) { if (var->fType.kind() == Type::kSampler_Kind) {
storageClass = SpvStorageClassUniformConstant; storageClass = SpvStorageClassUniformConstant;
} else { } else {
storageClass = SpvStorageClassUniform; storageClass = SpvStorageClassUniform;
@ -2388,36 +2390,37 @@ void SPIRVCodeGenerator::writeGlobalVars(const VarDeclaration& decl, std::ostrea
storageClass = SpvStorageClassPrivate; storageClass = SpvStorageClassPrivate;
} }
SpvId id = this->nextId(); SpvId id = this->nextId();
fVariableMap[decl.fVars[i]] = id; fVariableMap[var] = id;
SpvId type = this->getPointerType(decl.fVars[i]->fType, storageClass); SpvId type = this->getPointerType(var->fType, storageClass);
this->writeInstruction(SpvOpVariable, type, id, storageClass, fConstantBuffer); this->writeInstruction(SpvOpVariable, type, id, storageClass, fConstantBuffer);
this->writeInstruction(SpvOpName, id, decl.fVars[i]->fName.c_str(), fNameBuffer); this->writeInstruction(SpvOpName, id, var->fName.c_str(), fNameBuffer);
if (decl.fVars[i]->fType.kind() == Type::kMatrix_Kind) { if (var->fType.kind() == Type::kMatrix_Kind) {
this->writeInstruction(SpvOpMemberDecorate, id, (SpvId) i, SpvDecorationColMajor, this->writeInstruction(SpvOpMemberDecorate, id, (SpvId) i, SpvDecorationColMajor,
fDecorationBuffer); fDecorationBuffer);
this->writeInstruction(SpvOpMemberDecorate, id, (SpvId) i, SpvDecorationMatrixStride, 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); ASSERT(!fCurrentBlock);
fCurrentBlock = -1; fCurrentBlock = -1;
SpvId value = this->writeExpression(*decl.fValues[i], fGlobalInitializersBuffer); SpvId value = this->writeExpression(*varDecl.fValue, fGlobalInitializersBuffer);
this->writeInstruction(SpvOpStore, id, value, fGlobalInitializersBuffer); this->writeInstruction(SpvOpStore, id, value, fGlobalInitializersBuffer);
fCurrentBlock = 0; 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) { void SPIRVCodeGenerator::writeVarDeclarations(const VarDeclarations& decl, std::ostream& out) {
for (size_t i = 0; i < decl.fVars.size(); i++) { for (const auto& varDecl : decl.fVars) {
const Variable* var = varDecl.fVar;
SpvId id = this->nextId(); SpvId id = this->nextId();
fVariableMap[decl.fVars[i]] = id; fVariableMap[var] = id;
SpvId type = this->getPointerType(decl.fVars[i]->fType, SpvStorageClassFunction); SpvId type = this->getPointerType(var->fType, SpvStorageClassFunction);
this->writeInstruction(SpvOpVariable, type, id, SpvStorageClassFunction, fVariableBuffer); this->writeInstruction(SpvOpVariable, type, id, SpvStorageClassFunction, fVariableBuffer);
this->writeInstruction(SpvOpName, id, decl.fVars[i]->fName.c_str(), fNameBuffer); this->writeInstruction(SpvOpName, id, var->fName.c_str(), fNameBuffer);
if (decl.fValues[i]) { if (varDecl.fValue) {
SpvId value = this->writeExpression(*decl.fValues[i], out); SpvId value = this->writeExpression(*varDecl.fValue, out);
this->writeInstruction(SpvOpStore, id, value, out); this->writeInstruction(SpvOpStore, id, value, out);
} }
} }
@ -2434,8 +2437,8 @@ void SPIRVCodeGenerator::writeStatement(const Statement& s, std::ostream& out) {
case Statement::kReturn_Kind: case Statement::kReturn_Kind:
this->writeReturnStatement((ReturnStatement&) s, out); this->writeReturnStatement((ReturnStatement&) s, out);
break; break;
case Statement::kVarDeclaration_Kind: case Statement::kVarDeclarations_Kind:
this->writeVarDeclaration(*((VarDeclarationStatement&) s).fDeclaration, out); this->writeVarDeclarations(*((VarDeclarationsStatement&) s).fDeclaration, out);
break; break;
case Statement::kIf_Kind: case Statement::kIf_Kind:
this->writeIfStatement((IfStatement&) s, out); 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++) { for (size_t i = 0; i < program.fElements.size(); i++) {
if (program.fElements[i]->fKind == ProgramElement::kVar_Kind) { 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++) { for (size_t i = 0; i < program.fElements.size(); i++) {

View File

@ -115,9 +115,9 @@ private:
SpvId writeFunction(const FunctionDefinition& f, std::ostream& out); 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); SpvId writeVariableReference(const VariableReference& ref, std::ostream& out);

View File

@ -26,7 +26,7 @@ struct ASTInterfaceBlock : public ASTDeclaration {
ASTModifiers modifiers, ASTModifiers modifiers,
std::string interfaceName, std::string interfaceName,
std::string valueName, std::string valueName,
std::vector<std::unique_ptr<ASTVarDeclaration>> declarations) std::vector<std::unique_ptr<ASTVarDeclarations>> declarations)
: INHERITED(position, kInterfaceBlock_Kind) : INHERITED(position, kInterfaceBlock_Kind)
, fModifiers(modifiers) , fModifiers(modifiers)
, fInterfaceName(std::move(interfaceName)) , fInterfaceName(std::move(interfaceName))
@ -48,7 +48,7 @@ struct ASTInterfaceBlock : public ASTDeclaration {
const ASTModifiers fModifiers; const ASTModifiers fModifiers;
const std::string fInterfaceName; const std::string fInterfaceName;
const std::string fValueName; const std::string fValueName;
const std::vector<std::unique_ptr<ASTVarDeclaration>> fDeclarations; const std::vector<std::unique_ptr<ASTVarDeclarations>> fDeclarations;
typedef ASTDeclaration INHERITED; typedef ASTDeclaration INHERITED;
}; };

View File

@ -5,8 +5,8 @@
* found in the LICENSE file. * found in the LICENSE file.
*/ */
#ifndef SKSL_ASTVARDECLARATION #ifndef SKSL_ASTVARDECLARATIONS
#define SKSL_ASTVARDECLARATION #define SKSL_ASTVARDECLARATIONS
#include "SkSLASTDeclaration.h" #include "SkSLASTDeclaration.h"
#include "SkSLASTModifiers.h" #include "SkSLASTModifiers.h"
@ -17,51 +17,68 @@
namespace SkSL { namespace SkSL {
/** /**
* A variable declaration, which may consist of multiple individual variables. For instance * A single variable declaration within a var declaration statement. For instance, the statement
* 'int x, y = 1, z[4][2]' is a single ASTVarDeclaration. This declaration would have a type of * 'int x = 2, y[3];' is an ASTVarDeclarations statement containing two individual ASTVarDeclaration
* 'int', names ['x', 'y', 'z'], sizes of [[], [], [4, 2]], and values of [null, 1, null]. * instances.
*/ */
struct ASTVarDeclaration : public ASTDeclaration { struct ASTVarDeclaration {
ASTVarDeclaration(ASTModifiers modifiers, ASTVarDeclaration(const std::string name,
std::unique_ptr<ASTType> type, std::vector<std::unique_ptr<ASTExpression>> sizes,
std::vector<std::string> names, std::unique_ptr<ASTExpression> value)
std::vector<std::vector<std::unique_ptr<ASTExpression>>> sizes, : fName(name)
std::vector<std::unique_ptr<ASTExpression>> values)
: INHERITED(type->fPosition, kVar_Kind)
, fModifiers(modifiers)
, fType(std::move(type))
, fNames(std::move(names))
, fSizes(std::move(sizes)) , fSizes(std::move(sizes))
, fValues(std::move(values)) { , fValue(std::move(value)) {}
ASSERT(fNames.size() == fValues.size());
}
std::string description() const override { std::string description() const {
std::string result = fModifiers.description() + fType->description() + " "; std::string result = fName;
std::string separator = ""; for (const auto& size : fSizes) {
for (size_t i = 0; i < fNames.size(); i++) { if (size) {
result += separator; result += "[" + size->description() + "]";
separator = ", "; } else {
result += fNames[i]; result += "[]";
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();
} }
} }
if (fValue) {
result += " = " + fValue->description();
}
return result; 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))
, fVars(std::move(vars)) {}
std::string description() const override {
std::string result = fModifiers.description() + fType->description() + " ";
std::string separator = "";
for (const auto& var : fVars) {
result += separator;
separator = ", ";
result += var.description();
}
return result;
}
const ASTModifiers fModifiers; const ASTModifiers fModifiers;
const std::unique_ptr<ASTType> fType; const std::unique_ptr<ASTType> fType;
const std::vector<std::string> fNames; const std::vector<ASTVarDeclaration> fVars;
const std::vector<std::vector<std::unique_ptr<ASTExpression>>> fSizes;
const std::vector<std::unique_ptr<ASTExpression>> fValues;
typedef ASTDeclaration INHERITED; typedef ASTDeclaration INHERITED;
}; };

View File

@ -17,15 +17,15 @@ namespace SkSL {
* A variable declaration appearing as a statement within a function. * A variable declaration appearing as a statement within a function.
*/ */
struct ASTVarDeclarationStatement : public ASTStatement { struct ASTVarDeclarationStatement : public ASTStatement {
ASTVarDeclarationStatement(std::unique_ptr<ASTVarDeclaration> decl) ASTVarDeclarationStatement(std::unique_ptr<ASTVarDeclarations> decl)
: INHERITED(decl->fPosition, kVarDeclaration_Kind) : INHERITED(decl->fPosition, kVarDeclaration_Kind)
, fDeclaration(std::move(decl)) {} , fDeclarations(std::move(decl)) {}
std::string description() const override { std::string description() const override {
return fDeclaration->description() + ";"; return fDeclarations->description() + ";";
} }
std::unique_ptr<ASTVarDeclaration> fDeclaration; std::unique_ptr<ASTVarDeclarations> fDeclarations;
typedef ASTStatement INHERITED; typedef ASTStatement INHERITED;
}; };

View File

@ -27,7 +27,7 @@ struct Statement : public IRNode {
kFor_Kind, kFor_Kind,
kIf_Kind, kIf_Kind,
kReturn_Kind, kReturn_Kind,
kVarDeclaration_Kind, kVarDeclarations_Kind,
kWhile_Kind kWhile_Kind
}; };

View File

@ -5,8 +5,8 @@
* found in the LICENSE file. * found in the LICENSE file.
*/ */
#ifndef SKSL_VARDECLARATION #ifndef SKSL_VARDECLARATIONS
#define SKSL_VARDECLARATION #define SKSL_VARDECLARATIONS
#include "SkSLExpression.h" #include "SkSLExpression.h"
#include "SkSLStatement.h" #include "SkSLStatement.h"
@ -15,51 +15,65 @@
namespace SkSL { namespace SkSL {
/** /**
* A variable declaration, which may consist of multiple individual variables. For instance * A single variable declaration within a var declaration statement. For instance, the statement
* 'int x, y = 1, z[4][2];' is a single VarDeclaration. This declaration would have a base type of * 'int x = 2, y[3];' is a VarDeclarations statement containing two individual VarDeclaration
* 'int', names ['x', 'y', 'z'], sizes of [[], [], [4, 2]], and values of [null, 1, null]. * instances.
*/ */
struct VarDeclaration : public ProgramElement { struct VarDeclaration {
VarDeclaration(Position position, const Type* baseType, std::vector<const Variable*> vars, VarDeclaration(const Variable* var,
std::vector<std::vector<std::unique_ptr<Expression>>> sizes, std::vector<std::unique_ptr<Expression>> sizes,
std::vector<std::unique_ptr<Expression>> values) 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) : INHERITED(position, kVar_Kind)
, fBaseType(*baseType) , fBaseType(*baseType)
, fVars(std::move(vars)) , fVars(std::move(vars)) {}
, fSizes(std::move(sizes))
, fValues(std::move(values)) {}
std::string description() const override { std::string description() const override {
std::string result = fVars[0]->fModifiers.description(); if (!fVars.size()) {
const Type* baseType = &fVars[0]->fType; return "";
while (baseType->kind() == Type::kArray_Kind) {
baseType = &baseType->componentType();
} }
result += baseType->description(); std::string result = fVars[0].fVar->fModifiers.description() + fBaseType.description() +
std::string separator = " "; " ";
for (size_t i = 0; i < fVars.size(); i++) { std::string separator = "";
for (const auto& var : fVars) {
result += separator; result += separator;
separator = ", "; separator = ", ";
result += fVars[i]->fName; result += var.description();
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 += ";";
return result; return result;
} }
const Type& fBaseType; const Type& fBaseType;
const std::vector<const Variable*> fVars; const std::vector<VarDeclaration> fVars;
const std::vector<std::vector<std::unique_ptr<Expression>>> fSizes;
const std::vector<std::unique_ptr<Expression>> fValues;
typedef ProgramElement INHERITED; typedef ProgramElement INHERITED;
}; };

View File

@ -14,18 +14,18 @@
namespace SkSL { 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 { struct VarDeclarationsStatement : public Statement {
VarDeclarationStatement(std::unique_ptr<VarDeclaration> decl) VarDeclarationsStatement(std::unique_ptr<VarDeclarations> decl)
: INHERITED(decl->fPosition, kVarDeclaration_Kind) : INHERITED(decl->fPosition, kVarDeclarations_Kind)
, fDeclaration(std::move(decl)) {} , fDeclaration(std::move(decl)) {}
std::string description() const override { std::string description() const override {
return fDeclaration->description(); return fDeclaration->description();
} }
const std::shared_ptr<VarDeclaration> fDeclaration; const std::shared_ptr<VarDeclarations> fDeclaration;
typedef Statement INHERITED; typedef Statement INHERITED;
}; };