refactored SkSL VarDeclaration handling
authorethannicholas <ethannicholas@google.com>
Wed, 7 Sep 2016 20:37:16 +0000 (13:37 -0700)
committerCommit bot <commit-bot@chromium.org>
Wed, 7 Sep 2016 20:37:16 +0000 (13:37 -0700)
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2312233002

Review-Url: https://codereview.chromium.org/2312233002

15 files changed:
src/sksl/SkSLCompiler.cpp
src/sksl/SkSLGLSLCodeGenerator.cpp
src/sksl/SkSLGLSLCodeGenerator.h
src/sksl/SkSLIRGenerator.cpp
src/sksl/SkSLIRGenerator.h
src/sksl/SkSLParser.cpp
src/sksl/SkSLParser.h
src/sksl/SkSLSPIRVCodeGenerator.cpp
src/sksl/SkSLSPIRVCodeGenerator.h
src/sksl/ast/SkSLASTInterfaceBlock.h
src/sksl/ast/SkSLASTVarDeclaration.h
src/sksl/ast/SkSLASTVarDeclarationStatement.h
src/sksl/ir/SkSLStatement.h
src/sksl/ir/SkSLVarDeclaration.h
src/sksl/ir/SkSLVarDeclarationStatement.h

index f55150c..d2ad812 100644 (file)
@@ -148,8 +148,8 @@ void Compiler::internalConvertProgram(std::string text,
         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));
index 20a39cf..da0bcb9 100644 (file)
@@ -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;
index 76512e0..3534aff 100644 (file)
@@ -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);
 
index 9b0271b..c30cac1 100644 (file)
@@ -129,35 +129,32 @@ std::unique_ptr<Block> IRGenerator::convertBlock(const ASTBlock& block) {
 
 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;
                 }
@@ -175,39 +172,35 @@ std::unique_ptr<VarDeclaration> 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<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) {
@@ -482,21 +475,21 @@ std::unique_ptr<InterfaceBlock> IRGenerator::convertInterfaceBlock(const ASTInte
     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");
             }
         }        
index 2384b2d..a3ff210 100644 (file)
@@ -56,8 +56,8 @@ public:
     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);
index 65187c3..b240e45 100644 (file)
@@ -274,7 +274,7 @@ std::unique_ptr<ASTDeclaration> Parser::declaration() {
 }
 
 /* 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) {
@@ -301,23 +301,23 @@ std::unique_ptr<ASTType> Parser::structDeclaration() {
     }
     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");
             }
         }
@@ -331,20 +331,20 @@ std::unique_ptr<ASTType> Parser::structDeclaration() {
 }
 
 /* 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");
                 }
             }
@@ -357,12 +357,10 @@ std::unique_ptr<ASTVarDeclaration> Parser::structVarDeclaration(ASTModifiers mod
 
 /* (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();
@@ -380,26 +378,23 @@ std::unique_ptr<ASTVarDeclaration> Parser::varDeclarationEnd(ASTModifiers mods,
             }
         }
     }
-    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) {
@@ -416,26 +411,21 @@ std::unique_ptr<ASTVarDeclaration> Parser::varDeclarationEnd(ASTModifiers mods,
                 }
             }
         }
-        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)? */
@@ -614,7 +604,7 @@ std::unique_ptr<ASTStatement> 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<ASTStatement> 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<ASTDeclaration> Parser::interfaceBlock(ASTModifiers mods) {
         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;
         }
@@ -788,12 +778,12 @@ std::unique_ptr<ASTForStatement> Parser::forStatement() {
             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
index 45629a3..75f304b 100644 (file)
@@ -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<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();
 
index efa41bf..d17e3c4 100644 (file)
@@ -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++) {
index caae201..e7b2b30 100644 (file)
@@ -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);
 
index f501b12..c271362 100644 (file)
@@ -26,7 +26,7 @@ struct ASTInterfaceBlock : public ASTDeclaration {
                       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))
@@ -48,7 +48,7 @@ struct ASTInterfaceBlock : public ASTDeclaration {
     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;
 };
index 613867e..2eaf498 100644 (file)
@@ -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"
 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;
 };
index b647b6e..8bae389 100644 (file)
@@ -17,15 +17,15 @@ namespace SkSL {
  * 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;
 };
index 64b7bdf..012311f 100644 (file)
@@ -27,7 +27,7 @@ struct Statement : public IRNode {
         kFor_Kind,
         kIf_Kind,
         kReturn_Kind,
-        kVarDeclaration_Kind,
+        kVarDeclarations_Kind,
         kWhile_Kind
     };
 
index ca3c7f9..e64a874 100644 (file)
@@ -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"
 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;
 };
index e81c0ac..59d37ab 100644 (file)
 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;
 };