Non-functional. Rationalizations enabling future generalizations:
authorJohn Kessenich <cepheus@frii.com>
Thu, 29 Mar 2018 00:01:20 +0000 (18:01 -0600)
committerJohn Kessenich <cepheus@frii.com>
Thu, 29 Mar 2018 00:01:20 +0000 (18:01 -0600)
- Use much simpler method to update implicit array sizes.
  The previous overly complicated method was error prone.
- Rationalize all use of unsized arrays.
- Combine decorations when generating SPIR-V, to simplify
  adding extensions.

25 files changed:
SPIRV/GlslangToSpv.cpp
SPIRV/SpvBuilder.cpp
Test/array.frag
Test/baseResults/150.tesc.out
Test/baseResults/310.comp.out
Test/baseResults/310.tese.out
Test/baseResults/310AofA.vert.out
Test/baseResults/310implicitSizeArrayError.vert.out
Test/baseResults/320.tese.out
Test/baseResults/400.tese.out
Test/baseResults/420.vert.out
Test/baseResults/430.comp.out
Test/baseResults/array.frag.out
glslang/Include/Types.h
glslang/Include/arrays.h
glslang/Include/intermediate.h
glslang/MachineIndependent/ParseContextBase.cpp
glslang/MachineIndependent/ParseHelper.cpp
glslang/MachineIndependent/ParseHelper.h
glslang/MachineIndependent/glslang.y
glslang/MachineIndependent/glslang_tab.cpp
glslang/MachineIndependent/linkValidate.cpp
hlsl/hlslGrammar.cpp
hlsl/hlslParseHelper.cpp
hlsl/hlslParseHelper.h

index d4eaa90..5d7350f 100644 (file)
@@ -99,7 +99,13 @@ private:
     spv::Builder* builder_;
     bool previous_flag_;
 };
-}
+
+struct OpDecorations {
+    spv::Decoration precision;
+    spv::Decoration noContraction;
+};
+
+} // namespace
 
 //
 // The main holder of information for translating glslang to SPIR-V.
@@ -143,7 +149,8 @@ protected:
     spv::Id createInvertedSwizzle(spv::Decoration precision, const glslang::TIntermTyped&, spv::Id parentResult);
     void convertSwizzle(const glslang::TIntermAggregate&, std::vector<unsigned>& swizzle);
     spv::Id convertGlslangToSpvType(const glslang::TType& type);
-    spv::Id convertGlslangToSpvType(const glslang::TType& type, glslang::TLayoutPacking, const glslang::TQualifier&);
+    spv::Id convertGlslangToSpvType(const glslang::TType& type, glslang::TLayoutPacking, const glslang::TQualifier&,
+        bool lastBufferBlockMember);
     bool filterMember(const glslang::TType& member);
     spv::Id convertGlslangStructToSpvType(const glslang::TType&, const glslang::TTypeList* glslangStruct,
                                           glslang::TLayoutPacking, const glslang::TQualifier&);
@@ -172,11 +179,15 @@ protected:
     spv::Id createImageTextureFunctionCall(glslang::TIntermOperator* node);
     spv::Id handleUserFunctionCall(const glslang::TIntermAggregate*);
 
-    spv::Id createBinaryOperation(glslang::TOperator op, spv::Decoration precision, spv::Decoration noContraction, spv::Id typeId, spv::Id left, spv::Id right, glslang::TBasicType typeProxy, bool reduceComparison = true);
-    spv::Id createBinaryMatrixOperation(spv::Op, spv::Decoration precision, spv::Decoration noContraction, spv::Id typeId, spv::Id left, spv::Id right);
-    spv::Id createUnaryOperation(glslang::TOperator op, spv::Decoration precision, spv::Decoration noContraction, spv::Id typeId, spv::Id operand,glslang::TBasicType typeProxy);
-    spv::Id createUnaryMatrixOperation(spv::Op op, spv::Decoration precision, spv::Decoration noContraction, spv::Id typeId, spv::Id operand,glslang::TBasicType typeProxy);
-    spv::Id createConversion(glslang::TOperator op, spv::Decoration precision, spv::Decoration noContraction, spv::Id destTypeId, spv::Id operand, glslang::TBasicType typeProxy);
+    spv::Id createBinaryOperation(glslang::TOperator op, OpDecorations&, spv::Id typeId, spv::Id left, spv::Id right,
+                                  glslang::TBasicType typeProxy, bool reduceComparison = true);
+    spv::Id createBinaryMatrixOperation(spv::Op, OpDecorations&, spv::Id typeId, spv::Id left, spv::Id right);
+    spv::Id createUnaryOperation(glslang::TOperator op, OpDecorations&, spv::Id typeId, spv::Id operand,
+                                 glslang::TBasicType typeProxy);
+    spv::Id createUnaryMatrixOperation(spv::Op op, OpDecorations&, spv::Id typeId, spv::Id operand,
+                                       glslang::TBasicType typeProxy);
+    spv::Id createConversion(glslang::TOperator op, OpDecorations&, spv::Id destTypeId, spv::Id operand,
+                             glslang::TBasicType typeProxy);
     spv::Id createConversionOperation(glslang::TOperator op, spv::Id operand, int vectorSize);
     spv::Id makeSmearedConstant(spv::Id constant, int vectorSize);
     spv::Id createAtomicOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy);
@@ -1275,8 +1286,9 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
                 spv::Id leftRValue = accessChainLoad(node->getLeft()->getType());
 
                 // do the operation
-                rValue = createBinaryOperation(node->getOp(), TranslatePrecisionDecoration(node->getOperationPrecision()),
-                                               TranslateNoContractionDecoration(node->getType().getQualifier()),
+                OpDecorations decorations = { TranslatePrecisionDecoration(node->getOperationPrecision()),
+                                              TranslateNoContractionDecoration(node->getType().getQualifier()) };
+                rValue = createBinaryOperation(node->getOp(), decorations,
                                                convertGlslangToSpvType(node->getType()), leftRValue, rValue,
                                                node->getType().getBasicType());
 
@@ -1403,8 +1415,9 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
     spv::Id right = accessChainLoad(node->getRight()->getType());
 
     // get result
-    spv::Id result = createBinaryOperation(node->getOp(), TranslatePrecisionDecoration(node->getOperationPrecision()),
-                                           TranslateNoContractionDecoration(node->getType().getQualifier()),
+    OpDecorations decorations = { TranslatePrecisionDecoration(node->getOperationPrecision()),
+                                  TranslateNoContractionDecoration(node->getType().getQualifier()) };
+    spv::Id result = createBinaryOperation(node->getOp(), decorations,
                                            convertGlslangToSpvType(node->getType()), left, right,
                                            node->getLeft()->getType().getBasicType());
 
@@ -1445,7 +1458,7 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
         // Normal .length() would have been constant folded by the front-end.
         // So, this has to be block.lastMember.length().
         // SPV wants "block" and member number as the operands, go get them.
-        assert(node->getOperand()->getType().isRuntimeSizedArray());
+
         glslang::TIntermTyped* block = node->getOperand()->getAsBinaryNode()->getLeft();
         block->traverse(this);
         unsigned int member = node->getOperand()->getAsBinaryNode()->getRight()->getAsConstantUnion()->getConstArray()[0].getUConst();
@@ -1482,20 +1495,20 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
     else
         operand = accessChainLoad(node->getOperand()->getType());
 
-    spv::Decoration precision = TranslatePrecisionDecoration(node->getOperationPrecision());
-    spv::Decoration noContraction = TranslateNoContractionDecoration(node->getType().getQualifier());
+    OpDecorations decorations = { TranslatePrecisionDecoration(node->getOperationPrecision()),
+                                  TranslateNoContractionDecoration(node->getType().getQualifier()) };
 
     // it could be a conversion
     if (! result)
-        result = createConversion(node->getOp(), precision, noContraction, resultType(), operand, node->getOperand()->getBasicType());
+        result = createConversion(node->getOp(), decorations, resultType(), operand, node->getOperand()->getBasicType());
 
     // if not, then possibly an operation
     if (! result)
-        result = createUnaryOperation(node->getOp(), precision, noContraction, resultType(), operand, node->getOperand()->getBasicType());
+        result = createUnaryOperation(node->getOp(), decorations, resultType(), operand, node->getOperand()->getBasicType());
 
     if (result) {
         if (invertedType)
-            result = createInvertedSwizzle(precision, *node->getOperand(), result);
+            result = createInvertedSwizzle(decorations.precision, *node->getOperand(), result);
 
         builder.clearAccessChain();
         builder.setAccessChainRValue(result);
@@ -1533,8 +1546,7 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
             else
                 op = glslang::EOpSub;
 
-            spv::Id result = createBinaryOperation(op, precision,
-                                                   TranslateNoContractionDecoration(node->getType().getQualifier()),
+            spv::Id result = createBinaryOperation(op, decorations,
                                                    convertGlslangToSpvType(node->getType()), operand, one,
                                                    node->getType().getBasicType());
             assert(result != spv::NoResult);
@@ -1922,7 +1934,9 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
         spv::Id rightId = accessChainLoad(right->getType());
 
         builder.setLine(node->getLoc().line);
-        result = createBinaryOperation(binOp, precision, TranslateNoContractionDecoration(node->getType().getQualifier()),
+        OpDecorations decorations = { precision,
+                                      TranslateNoContractionDecoration(node->getType().getQualifier()) };
+        result = createBinaryOperation(binOp, decorations,
                                        resultType(), leftId, rightId,
                                        left->getType().getBasicType(), reduceComparison);
 
@@ -2020,11 +2034,14 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
             result = createNoArgOperation(node->getOp(), precision, resultType());
             break;
         case 1:
-            result = createUnaryOperation(
-                node->getOp(), precision,
-                TranslateNoContractionDecoration(node->getType().getQualifier()),
-                resultType(), operands.front(),
-                glslangOperands[0]->getAsTyped()->getBasicType());
+            {
+                OpDecorations decorations = { precision, 
+                                              TranslateNoContractionDecoration(node->getType().getQualifier()) };
+                result = createUnaryOperation(
+                    node->getOp(), decorations,
+                    resultType(), operands.front(),
+                    glslangOperands[0]->getAsTyped()->getBasicType());
+            }
             break;
         default:
             result = createMiscOperation(node->getOp(), precision, resultType(), operands, node->getBasicType());
@@ -2471,13 +2488,14 @@ void TGlslangToSpvTraverser::convertSwizzle(const glslang::TIntermAggregate& nod
 // layout state rooted from the top-level type.
 spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& type)
 {
-    return convertGlslangToSpvType(type, getExplicitLayout(type), type.getQualifier());
+    return convertGlslangToSpvType(type, getExplicitLayout(type), type.getQualifier(), false);
 }
 
 // Do full recursive conversion of an arbitrary glslang type to a SPIR-V Id.
 // explicitLayout can be kept the same throughout the hierarchical recursive walk.
 // Mutually recursive with convertGlslangStructToSpvType().
-spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& type, glslang::TLayoutPacking explicitLayout, const glslang::TQualifier& qualifier)
+spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& type,
+    glslang::TLayoutPacking explicitLayout, const glslang::TQualifier& qualifier, bool lastBufferBlockMember)
 {
     spv::Id spvType = spv::NoResult;
 
@@ -2630,13 +2648,12 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
                 stride = getArrayStride(type, explicitLayout, qualifier.layoutMatrix);
         }
 
-        // Do the outer dimension, which might not be known for a runtime-sized array
-        if (type.isRuntimeSizedArray()) {
-            spvType = builder.makeRuntimeArray(spvType);
-        } else {
-            assert(type.getOuterArraySize() > 0);
+        // Do the outer dimension, which might not be known for a runtime-sized array.
+        // (Unsized arrays that survive through linking will be runtime-sized arrays)
+        if (type.isSizedArray())
             spvType = builder.makeArrayType(spvType, makeArraySizeId(*type.getArraySizes(), 0), stride);
-        }
+        else
+            spvType = builder.makeRuntimeArray(spvType);
         if (stride > 0)
             builder.addDecoration(spvType, spv::DecorationArrayStride, stride);
     }
@@ -2703,7 +2720,10 @@ spv::Id TGlslangToSpvTraverser::convertGlslangStructToSpvType(const glslang::TTy
                 memberQualifier.layoutLocation = qualifier.layoutLocation;
 
             // recurse
-            spvMembers.push_back(convertGlslangToSpvType(glslangMember, explicitLayout, memberQualifier));
+            bool lastBufferBlockMember = qualifier.storage == glslang::EvqBuffer &&
+                                         i == (int)glslangMembers->size() - 1;
+            spvMembers.push_back(
+                convertGlslangToSpvType(glslangMember, explicitLayout, memberQualifier, lastBufferBlockMember));
         }
     }
 
@@ -2805,6 +2825,12 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
         if (builtIn != spv::BuiltInMax)
             builder.addMemberDecoration(spvType, member, spv::DecorationBuiltIn, (int)builtIn);
 
+        if (glslangIntermediate->getHlslFunctionality1() && memberQualifier.semanticName != nullptr) {
+            builder.addExtension("SPV_GOOGLE_hlsl_functionality1");
+            builder.addMemberDecoration(spvType, member, (spv::Decoration)spv::DecorationHlslSemanticGOOGLE,
+                                        memberQualifier.semanticName);
+        }
+
 #ifdef NV_EXTENSIONS
         if (builtIn == spv::BuiltInLayer) {
             // SPV_NV_viewport_array2 extension
@@ -2827,11 +2853,6 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
             builder.addExtension(spv::E_SPV_NV_geometry_shader_passthrough);
         }
 #endif
-        if (glslangIntermediate->getHlslFunctionality1() && memberQualifier.semanticName != nullptr) {
-            builder.addExtension("SPV_GOOGLE_hlsl_functionality1");
-            builder.addMemberDecoration(spvType, member, (spv::Decoration)spv::DecorationHlslSemanticGOOGLE,
-                                        memberQualifier.semanticName);
-        }
     }
 
     // Decorate the structure
@@ -3937,8 +3958,7 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg
 }
 
 // Translate AST operation to SPV operation, already having SPV-based operands/types.
-spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, spv::Decoration precision,
-                                                      spv::Decoration noContraction,
+spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, OpDecorations& decorations,
                                                       spv::Id typeId, spv::Id left, spv::Id right,
                                                       glslang::TBasicType typeProxy, bool reduceComparison)
 {
@@ -4075,15 +4095,15 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, spv
     if (binOp != spv::OpNop) {
         assert(comparison == false);
         if (builder.isMatrix(left) || builder.isMatrix(right))
-            return createBinaryMatrixOperation(binOp, precision, noContraction, typeId, left, right);
+            return createBinaryMatrixOperation(binOp, decorations, typeId, left, right);
 
         // No matrix involved; make both operands be the same number of components, if needed
         if (needMatchingVectors)
-            builder.promoteScalar(precision, left, right);
+            builder.promoteScalar(decorations.precision, left, right);
 
         spv::Id result = builder.createBinOp(binOp, typeId, left, right);
-        builder.addDecoration(result, noContraction);
-        return builder.setPrecision(result, precision);
+        builder.addDecoration(result, decorations.noContraction);
+        return builder.setPrecision(result, decorations.precision);
     }
 
     if (! comparison)
@@ -4092,8 +4112,10 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, spv
     // Handle comparison instructions
 
     if (reduceComparison && (op == glslang::EOpEqual || op == glslang::EOpNotEqual)
-                         && (builder.isVector(left) || builder.isMatrix(left) || builder.isAggregate(left)))
-        return builder.createCompositeCompare(precision, left, right, op == glslang::EOpEqual);
+                         && (builder.isVector(left) || builder.isMatrix(left) || builder.isAggregate(left))) {
+        spv::Id result = builder.createCompositeCompare(decorations.precision, left, right, op == glslang::EOpEqual);
+        return result;
+    }
 
     switch (op) {
     case glslang::EOpLessThan:
@@ -4152,8 +4174,8 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, spv
 
     if (binOp != spv::OpNop) {
         spv::Id result = builder.createBinOp(binOp, typeId, left, right);
-        builder.addDecoration(result, noContraction);
-        return builder.setPrecision(result, precision);
+        builder.addDecoration(result, decorations.noContraction);
+        return builder.setPrecision(result, decorations.precision);
     }
 
     return 0;
@@ -4173,7 +4195,8 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, spv
 //   matrix op scalar    op in {+, -, /}
 //   scalar op matrix    op in {+, -, /}
 //
-spv::Id TGlslangToSpvTraverser::createBinaryMatrixOperation(spv::Op op, spv::Decoration precision, spv::Decoration noContraction, spv::Id typeId, spv::Id left, spv::Id right)
+spv::Id TGlslangToSpvTraverser::createBinaryMatrixOperation(spv::Op op, OpDecorations& decorations, spv::Id typeId,
+                                                            spv::Id left, spv::Id right)
 {
     bool firstClass = true;
 
@@ -4212,8 +4235,8 @@ spv::Id TGlslangToSpvTraverser::createBinaryMatrixOperation(spv::Op op, spv::Dec
 
     if (firstClass) {
         spv::Id result = builder.createBinOp(op, typeId, left, right);
-        builder.addDecoration(result, noContraction);
-        return builder.setPrecision(result, precision);
+        builder.addDecoration(result, decorations.noContraction);
+        return builder.setPrecision(result, decorations.precision);
     }
 
     // Handle component-wise +, -, *, %, and / for all combinations of type.
@@ -4240,9 +4263,9 @@ spv::Id TGlslangToSpvTraverser::createBinaryMatrixOperation(spv::Op op, spv::Dec
         std::vector<spv::Id> results;
         spv::Id smearVec = spv::NoResult;
         if (builder.isScalar(left))
-            smearVec = builder.smearScalar(precision, left, vecType);
+            smearVec = builder.smearScalar(decorations.precision, left, vecType);
         else if (builder.isScalar(right))
-            smearVec = builder.smearScalar(precision, right, vecType);
+            smearVec = builder.smearScalar(decorations.precision, right, vecType);
 
         // do each vector op
         for (unsigned int c = 0; c < numCols; ++c) {
@@ -4251,12 +4274,13 @@ spv::Id TGlslangToSpvTraverser::createBinaryMatrixOperation(spv::Op op, spv::Dec
             spv::Id  leftVec =  leftMat ? builder.createCompositeExtract( left, vecType, indexes) : smearVec;
             spv::Id rightVec = rightMat ? builder.createCompositeExtract(right, vecType, indexes) : smearVec;
             spv::Id result = builder.createBinOp(op, vecType, leftVec, rightVec);
-            builder.addDecoration(result, noContraction);
-            results.push_back(builder.setPrecision(result, precision));
+            builder.addDecoration(result, decorations.noContraction);
+            results.push_back(builder.setPrecision(result, decorations.precision));
         }
 
         // put the pieces together
-        return  builder.setPrecision(builder.createCompositeConstruct(typeId, results), precision);
+        spv::Id result = builder.setPrecision(builder.createCompositeConstruct(typeId, results), decorations.precision);
+        return result;
     }
     default:
         assert(0);
@@ -4264,7 +4288,8 @@ spv::Id TGlslangToSpvTraverser::createBinaryMatrixOperation(spv::Op op, spv::Dec
     }
 }
 
-spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, spv::Decoration precision, spv::Decoration noContraction, spv::Id typeId, spv::Id operand, glslang::TBasicType typeProxy)
+spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDecorations& decorations, spv::Id typeId,
+                                                     spv::Id operand, glslang::TBasicType typeProxy)
 {
     spv::Op unaryOp = spv::OpNop;
     int extBuiltins = -1;
@@ -4277,7 +4302,7 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, spv:
         if (isFloat) {
             unaryOp = spv::OpFNegate;
             if (builder.isMatrixType(typeId))
-                return createUnaryMatrixOperation(unaryOp, precision, noContraction, typeId, operand, typeProxy);
+                return createUnaryMatrixOperation(unaryOp, decorations, typeId, operand, typeProxy);
         } else
             unaryOp = spv::OpSNegate;
         break;
@@ -4538,7 +4563,7 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, spv:
         // Handle all of the atomics in one place, in createAtomicOperation()
         std::vector<spv::Id> operands;
         operands.push_back(operand);
-        return createAtomicOperation(op, precision, typeId, operands, typeProxy);
+        return createAtomicOperation(op, decorations.precision, typeId, operands, typeProxy);
     }
 
     case glslang::EOpBitFieldReverse:
@@ -4656,12 +4681,13 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, spv:
         id = builder.createUnaryOp(unaryOp, typeId, operand);
     }
 
-    builder.addDecoration(id, noContraction);
-    return builder.setPrecision(id, precision);
+    builder.addDecoration(id, decorations.noContraction);
+    return builder.setPrecision(id, decorations.precision);
 }
 
 // Create a unary operation on a matrix
-spv::Id TGlslangToSpvTraverser::createUnaryMatrixOperation(spv::Op op, spv::Decoration precision, spv::Decoration noContraction, spv::Id typeId, spv::Id operand, glslang::TBasicType /* typeProxy */)
+spv::Id TGlslangToSpvTraverser::createUnaryMatrixOperation(spv::Op op, OpDecorations& decorations, spv::Id typeId,
+                                                           spv::Id operand, glslang::TBasicType /* typeProxy */)
 {
     // Handle unary operations vector by vector.
     // The result type is the same type as the original type.
@@ -4683,12 +4709,13 @@ spv::Id TGlslangToSpvTraverser::createUnaryMatrixOperation(spv::Op op, spv::Deco
         indexes.push_back(c);
         spv::Id srcVec  = builder.createCompositeExtract(operand, srcVecType, indexes);
         spv::Id destVec = builder.createUnaryOp(op, destVecType, srcVec);
-        builder.addDecoration(destVec, noContraction);
-        results.push_back(builder.setPrecision(destVec, precision));
+        builder.addDecoration(destVec, decorations.noContraction);
+        results.push_back(builder.setPrecision(destVec, decorations.precision));
     }
 
     // put the pieces together
-    return builder.setPrecision(builder.createCompositeConstruct(typeId, results), precision);
+    spv::Id result = builder.setPrecision(builder.createCompositeConstruct(typeId, results), decorations.precision);
+    return result;
 }
 
 spv::Id TGlslangToSpvTraverser::createConversionOperation(glslang::TOperator op, spv::Id operand, int vectorSize)
@@ -4808,7 +4835,8 @@ spv::Id TGlslangToSpvTraverser::createConversionOperation(glslang::TOperator op,
     return result;
 }
 
-spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, spv::Decoration precision, spv::Decoration noContraction, spv::Id destType, spv::Id operand, glslang::TBasicType typeProxy)
+spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecorations& decorations, spv::Id destType,
+                                                 spv::Id operand, glslang::TBasicType typeProxy)
 {
     spv::Op convOp = spv::OpNop;
     spv::Id zero = 0;
@@ -4963,7 +4991,7 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, spv::Dec
     case glslang::EOpConvFloat16ToFloat:
         convOp = spv::OpFConvert;
         if (builder.isMatrixType(destType))
-            return createUnaryMatrixOperation(convOp, precision, noContraction, destType, operand, typeProxy);
+            return createUnaryMatrixOperation(convOp, decorations, destType, operand, typeProxy);
         break;
 
     case glslang::EOpConvFloat16ToInt8:
@@ -5143,7 +5171,8 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, spv::Dec
     } else
         result = builder.createUnaryOp(convOp, destType, operand);
 
-    return builder.setPrecision(result, precision);
+    result = builder.setPrecision(result, decorations.precision);
+    return result;
 }
 
 spv::Id TGlslangToSpvTraverser::makeSmearedConstant(spv::Id constant, int vectorSize)
index dfeae87..1660787 100644 (file)
@@ -854,9 +854,9 @@ Id Builder::makeFpConstant(Id type, double d, bool specConstant)
 
         switch (getScalarTypeWidth(type)) {
         case 16:
-                return makeFloat16Constant(d, specConstant);
+                return makeFloat16Constant((float)d, specConstant);
         case 32:
-                return makeFloatConstant(d, specConstant);
+                return makeFloatConstant((float)d, specConstant);
         case 64:
                 return makeDoubleConstant(d, specConstant);
         default:
index 4ccb00c..63d5f4c 100644 (file)
@@ -104,3 +104,9 @@ void foo3()
 int[] i = int[]();    // ERROR, need constructor arguments
 float emptyA[];\r
 float b = vec4(emptyA);    // ERROR, array can't be a constructor argument\r
+uniform sampler2D s2d[];\r
+\r
+void foo4()\r
+{\r
+    s2d[a];           // ERROR, can't variably index unsized array\r
+}\r
index 4eb148c..0abe12d 100644 (file)
@@ -453,7 +453,7 @@ ERROR: 0:47: 'patch' : cannot use interpolation qualifiers with patch
 ERROR: 0:48: 'patch' : cannot use interpolation qualifiers with patch 
 ERROR: 0:49: 'patch' : cannot use interpolation qualifiers with patch 
 ERROR: 0:50: '' : can only have one auxiliary qualifier (centroid, patch, and sample) 
-ERROR: 0:54: 'gl_PerVertex' : block already declared with size, can't redeclare as implicitly-sized 
+ERROR: 0:54: 'gl_PerVertex' : block already declared with size, can't redeclare as unsized 
 ERROR: 0:59: 'gl_PerVertex' : can only redeclare a built-in block once, and before any use 
 ERROR: 0:64: 'quads' : cannot apply to 'out' 
 ERROR: 0:64: 'cw' : can only apply to 'in' 
index cad13f8..5a926f6 100644 (file)
@@ -102,13 +102,13 @@ ERROR: node is still EOpNull!
 0:35      GroupMemoryBarrier ( global void)
 0:36      move second child to first child ( temp highp int)
 0:36        value: direct index for structure (layout( column_major shared) buffer highp int)
-0:36          'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 1-element array of highp float values})
+0:36          'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer runtime-sized array of highp float values})
 0:36          Constant:
 0:36            0 (const uint)
 0:36        Convert float to int ( temp highp int)
 0:36          indirect index (layout( column_major shared) temp highp float)
-0:36            values: direct index for structure (layout( column_major shared) buffer unsized 1-element array of highp float)
-0:36              'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 1-element array of highp float values})
+0:36            values: direct index for structure (layout( column_major shared) buffer runtime-sized array of highp float)
+0:36              'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer runtime-sized array of highp float values})
 0:36              Constant:
 0:36                1 (const uint)
 0:36            'gl_LocalInvocationIndex' ( in highp uint LocalInvocationIndex)
@@ -117,8 +117,8 @@ ERROR: node is still EOpNull!
 0:61    Sequence
 0:61      move second child to first child ( temp highp float)
 0:61        direct index (layout( column_major shared) temp highp float)
-0:61          values: direct index for structure (layout( column_major shared) buffer unsized 1-element array of highp float)
-0:61            'ro' (layout( column_major shared) readonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 1-element array of highp float values})
+0:61          values: direct index for structure (layout( column_major shared) buffer unsized 3-element array of highp float)
+0:61            'ro' (layout( column_major shared) readonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:61            Constant:
 0:61              1 (const int)
 0:61          Constant:
@@ -126,8 +126,8 @@ ERROR: node is still EOpNull!
 0:61        Constant:
 0:61          4.700000
 0:62      array length ( temp int)
-0:62        values: direct index for structure (layout( column_major shared) buffer unsized 1-element array of highp float)
-0:62          'ro' (layout( column_major shared) readonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 1-element array of highp float values})
+0:62        values: direct index for structure (layout( column_major shared) buffer unsized 3-element array of highp float)
+0:62          'ro' (layout( column_major shared) readonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:62          Constant:
 0:62            1 (const int)
 0:63      Pre-Increment ( temp highp 4-component vector of float)
@@ -280,8 +280,8 @@ ERROR: node is still EOpNull!
 0:194      move second child to first child ( temp highp float)
 0:194        'g' ( temp highp float)
 0:194        direct index (layout( column_major shared) temp highp float)
-0:194          values: direct index for structure (layout( column_major shared) buffer unsized 1-element array of highp float)
-0:194            'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 1-element array of highp float values})
+0:194          values: direct index for structure (layout( column_major shared) buffer unsized 3-element array of highp float)
+0:194            'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:194            Constant:
 0:194              1 (const int)
 0:194          Constant:
@@ -290,24 +290,24 @@ ERROR: node is still EOpNull!
 0:195        move second child to first child ( temp highp float)
 0:195          'f' ( temp highp float)
 0:195          direct index (layout( column_major shared) temp highp float)
-0:195            values: direct index for structure (layout( column_major shared) buffer unsized 1-element array of highp float)
-0:195              'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 1-element array of highp float values})
+0:195            values: direct index for structure (layout( column_major shared) buffer unsized 3-element array of highp float)
+0:195              'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:195              Constant:
 0:195                1 (const int)
 0:195            Constant:
 0:195              2 (const int)
 0:196      Pre-Increment ( temp highp float)
 0:196        direct index (layout( column_major shared) temp highp float)
-0:196          values: direct index for structure (layout( column_major shared) buffer unsized 1-element array of highp float)
-0:196            'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 1-element array of highp float values})
+0:196          values: direct index for structure (layout( column_major shared) buffer unsized 3-element array of highp float)
+0:196            'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:196            Constant:
 0:196              1 (const int)
 0:196          Constant:
 0:196            2 (const int)
 0:197      Post-Decrement ( temp highp float)
 0:197        direct index (layout( column_major shared) temp highp float)
-0:197          values: direct index for structure (layout( column_major shared) buffer unsized 1-element array of highp float)
-0:197            'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 1-element array of highp float values})
+0:197          values: direct index for structure (layout( column_major shared) buffer unsized 3-element array of highp float)
+0:197            'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:197            Constant:
 0:197              1 (const int)
 0:197          Constant:
@@ -315,16 +315,16 @@ ERROR: node is still EOpNull!
 0:198      add ( temp highp float)
 0:198        'f' ( temp highp float)
 0:198        direct index (layout( column_major shared) temp highp float)
-0:198          values: direct index for structure (layout( column_major shared) buffer unsized 1-element array of highp float)
-0:198            'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 1-element array of highp float values})
+0:198          values: direct index for structure (layout( column_major shared) buffer unsized 3-element array of highp float)
+0:198            'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:198            Constant:
 0:198              1 (const int)
 0:198          Constant:
 0:198            2 (const int)
 0:199      subtract ( temp highp float)
 0:199        direct index (layout( column_major shared) temp highp float)
-0:199          values: direct index for structure (layout( column_major shared) buffer unsized 1-element array of highp float)
-0:199            'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 1-element array of highp float values})
+0:199          values: direct index for structure (layout( column_major shared) buffer unsized 3-element array of highp float)
+0:199            'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:199            Constant:
 0:199              1 (const int)
 0:199          Constant:
@@ -337,8 +337,8 @@ ERROR: node is still EOpNull!
 0:201        'f' ( temp highp float)
 0:201        false case
 0:201        direct index (layout( column_major shared) temp highp float)
-0:201          values: direct index for structure (layout( column_major shared) buffer unsized 1-element array of highp float)
-0:201            'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 1-element array of highp float values})
+0:201          values: direct index for structure (layout( column_major shared) buffer unsized 3-element array of highp float)
+0:201            'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:201            Constant:
 0:201              1 (const int)
 0:201          Constant:
@@ -348,8 +348,8 @@ ERROR: node is still EOpNull!
 0:202        'b' ( temp bool)
 0:202        true case
 0:202        direct index (layout( column_major shared) temp highp float)
-0:202          values: direct index for structure (layout( column_major shared) buffer unsized 1-element array of highp float)
-0:202            'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 1-element array of highp float values})
+0:202          values: direct index for structure (layout( column_major shared) buffer unsized 3-element array of highp float)
+0:202            'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:202            Constant:
 0:202              1 (const int)
 0:202          Constant:
@@ -361,8 +361,8 @@ ERROR: node is still EOpNull!
 0:203        Compare Equal ( temp bool)
 0:203          'f' ( temp highp float)
 0:203          direct index (layout( column_major shared) temp highp float)
-0:203            values: direct index for structure (layout( column_major shared) buffer unsized 1-element array of highp float)
-0:203              'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 1-element array of highp float values})
+0:203            values: direct index for structure (layout( column_major shared) buffer unsized 3-element array of highp float)
+0:203              'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:203              Constant:
 0:203                1 (const int)
 0:203            Constant:
@@ -375,8 +375,8 @@ ERROR: node is still EOpNull!
 0:205        Compare Greater Than or Equal ( temp bool)
 0:205          'f' ( temp highp float)
 0:205          direct index (layout( column_major shared) temp highp float)
-0:205            values: direct index for structure (layout( column_major shared) buffer unsized 1-element array of highp float)
-0:205              'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 1-element array of highp float values})
+0:205            values: direct index for structure (layout( column_major shared) buffer unsized 3-element array of highp float)
+0:205              'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:205              Constant:
 0:205                1 (const int)
 0:205            Constant:
@@ -389,8 +389,8 @@ ERROR: node is still EOpNull!
 0:207        direct index ( temp highp float)
 0:207          Construct vec3 ( temp highp 3-component vector of float)
 0:207            direct index (layout( column_major shared) temp highp float)
-0:207              values: direct index for structure (layout( column_major shared) buffer unsized 1-element array of highp float)
-0:207                'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 1-element array of highp float values})
+0:207              values: direct index for structure (layout( column_major shared) buffer unsized 3-element array of highp float)
+0:207                'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:207                Constant:
 0:207                  1 (const int)
 0:207              Constant:
@@ -399,13 +399,13 @@ ERROR: node is still EOpNull!
 0:207            0 (const int)
 0:208      Bitwise not ( temp highp int)
 0:208        value: direct index for structure (layout( column_major shared) buffer highp int)
-0:208          'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 1-element array of highp float values})
+0:208          'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:208          Constant:
 0:208            0 (const int)
 0:209      move second child to first child ( temp highp float)
 0:209        direct index (layout( column_major shared) temp highp float)
-0:209          values: direct index for structure (layout( column_major shared) buffer unsized 1-element array of highp float)
-0:209            'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 1-element array of highp float values})
+0:209          values: direct index for structure (layout( column_major shared) buffer unsized 3-element array of highp float)
+0:209            'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:209            Constant:
 0:209              1 (const int)
 0:209          Constant:
@@ -418,21 +418,21 @@ ERROR: node is still EOpNull!
 0:221      move second child to first child ( temp highp float)
 0:221        'g' ( temp highp float)
 0:221        direct index (layout( column_major shared) temp highp float)
-0:221          values: direct index for structure (layout( column_major shared) buffer unsized 1-element array of highp float)
-0:221            'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 1-element array of highp float values})
+0:221          values: direct index for structure (layout( column_major shared) buffer unsized 3-element array of highp float)
+0:221            'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:221            Constant:
 0:221              1 (const int)
 0:221          Constant:
 0:221            2 (const int)
 0:222      Bitwise not ( temp highp int)
 0:222        value: direct index for structure (layout( column_major shared) buffer highp int)
-0:222          'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 1-element array of highp float values})
+0:222          'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:222          Constant:
 0:222            0 (const int)
 0:223      move second child to first child ( temp highp float)
 0:223        direct index (layout( column_major shared) temp highp float)
-0:223          values: direct index for structure (layout( column_major shared) buffer unsized 1-element array of highp float)
-0:223            'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 1-element array of highp float values})
+0:223          values: direct index for structure (layout( column_major shared) buffer unsized 3-element array of highp float)
+0:223            'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:223            Constant:
 0:223              1 (const int)
 0:223          Constant:
@@ -441,7 +441,7 @@ ERROR: node is still EOpNull!
 0:223          3.400000
 0:224      move second child to first child ( temp highp int)
 0:224        value: direct index for structure (layout( column_major shared) buffer highp int)
-0:224          'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 1-element array of highp float values})
+0:224          'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:224          Constant:
 0:224            0 (const int)
 0:224        Constant:
@@ -463,7 +463,7 @@ ERROR: node is still EOpNull!
 0:?       4096 (const uint)
 0:?     'total' ( const highp int)
 0:?       66592 (const int)
-0:?     'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 1-element array of highp float values})
+0:?     'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer runtime-sized array of highp float values})
 0:?     'invalid' (layout( column_major shared) buffer block{layout( column_major shared) buffer unsized 1-element array of highp float values, layout( column_major shared) buffer highp int value})
 0:?     'v3' (layout( location=2) in highp 3-component vector of float)
 0:?     'f' ( in highp float)
@@ -474,7 +474,7 @@ ERROR: node is still EOpNull!
 0:?     'arrX' ( global 2-element array of highp int)
 0:?     'arrY' ( global 1-element array of highp int)
 0:?     'arrZ' ( global 4096-element array of highp int)
-0:?     'ro' (layout( column_major shared) readonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 1-element array of highp float values})
+0:?     'ro' (layout( column_major shared) readonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:?     'v' ( buffer highp 4-component vector of float)
 0:?     'us2dbad' ( uniform mediump usampler2D)
 0:?     'us2d' ( uniform highp usampler2D)
@@ -513,7 +513,7 @@ ERROR: node is still EOpNull!
 0:?     'badQ1' (layout( rgba32f) coherent volatile restrict uniform highp image2D)
 0:?     'badQ2' (layout( rgba8i) coherent volatile restrict uniform highp iimage2D)
 0:?     'badQ3' (layout( rgba16ui) coherent volatile restrict uniform highp uimage2D)
-0:?     'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 1-element array of highp float values})
+0:?     'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:?     'multio' (layout( column_major shared) buffer block{layout( column_major shared) readonly buffer highp int value, layout( column_major shared) writeonly buffer unsized 1-element array of highp float values})
 0:?     'inbi' ( in block{ in highp int a})
 0:?     'outbi' ( out block{ out highp int a})
@@ -540,13 +540,13 @@ ERROR: node is still EOpNull!
 0:35      GroupMemoryBarrier ( global void)
 0:36      move second child to first child ( temp highp int)
 0:36        value: direct index for structure (layout( column_major shared) buffer highp int)
-0:36          'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 1-element array of highp float values})
+0:36          'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer runtime-sized array of highp float values})
 0:36          Constant:
 0:36            0 (const uint)
 0:36        Convert float to int ( temp highp int)
 0:36          indirect index (layout( column_major shared) temp highp float)
-0:36            values: direct index for structure (layout( column_major shared) buffer unsized 1-element array of highp float)
-0:36              'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 1-element array of highp float values})
+0:36            values: direct index for structure (layout( column_major shared) buffer runtime-sized array of highp float)
+0:36              'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer runtime-sized array of highp float values})
 0:36              Constant:
 0:36                1 (const uint)
 0:36            'gl_LocalInvocationIndex' ( in highp uint LocalInvocationIndex)
@@ -557,8 +557,8 @@ ERROR: node is still EOpNull!
 0:?       4096 (const uint)
 0:?     'total' ( const highp int)
 0:?       66592 (const int)
-0:?     'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 1-element array of highp float values})
-0:?     'invalid' (layout( column_major shared) buffer block{layout( column_major shared) buffer unsized 1-element array of highp float values, layout( column_major shared) buffer highp int value})
+0:?     'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer runtime-sized array of highp float values})
+0:?     'invalid' (layout( column_major shared) buffer block{layout( column_major shared) buffer 1-element array of highp float values, layout( column_major shared) buffer highp int value})
 0:?     'v3' (layout( location=2) in highp 3-component vector of float)
 0:?     'f' ( in highp float)
 0:?     'fo' ( out highp float)
@@ -568,7 +568,7 @@ ERROR: node is still EOpNull!
 0:?     'arrX' ( global 2-element array of highp int)
 0:?     'arrY' ( global 1-element array of highp int)
 0:?     'arrZ' ( global 4096-element array of highp int)
-0:?     'ro' (layout( column_major shared) readonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 1-element array of highp float values})
+0:?     'ro' (layout( column_major shared) readonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:?     'v' ( buffer highp 4-component vector of float)
 0:?     'us2dbad' ( uniform mediump usampler2D)
 0:?     'us2d' ( uniform highp usampler2D)
@@ -607,7 +607,7 @@ ERROR: node is still EOpNull!
 0:?     'badQ1' (layout( rgba32f) coherent volatile restrict uniform highp image2D)
 0:?     'badQ2' (layout( rgba8i) coherent volatile restrict uniform highp iimage2D)
 0:?     'badQ3' (layout( rgba16ui) coherent volatile restrict uniform highp uimage2D)
-0:?     'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 1-element array of highp float values})
+0:?     'wo' (layout( column_major shared) writeonly buffer block{layout( column_major shared) buffer highp int value, layout( column_major shared) buffer unsized 3-element array of highp float values})
 0:?     'multio' (layout( column_major shared) buffer block{layout( column_major shared) readonly buffer highp int value, layout( column_major shared) writeonly buffer unsized 1-element array of highp float values})
 0:?     'inbi' ( in block{ in highp int a})
 0:?     'outbi' ( out block{ out highp int a})
index 7c74e3d..7d91e93 100644 (file)
@@ -25,7 +25,7 @@ ERROR: 0:53: 'noperspective' : not supported for this version or the enabled ext
 ERROR: 0:53: 'patch' : cannot use interpolation qualifiers with patch 
 ERROR: 0:54: 'sample' : Reserved word. 
 ERROR: 0:54: '' : can only have one auxiliary qualifier (centroid, patch, and sample) 
-ERROR: 0:58: 'gl_PerVertex' : block already declared with size, can't redeclare as implicitly-sized 
+ERROR: 0:58: 'gl_PerVertex' : block already declared with size, can't redeclare as unsized 
 ERROR: 0:63: 'gl_PerVertex' : can only redeclare a built-in block once, and before any use 
 ERROR: 0:68: 'quads' : cannot apply to 'out' 
 ERROR: 0:68: 'cw' : can only apply to 'in' 
index 96c5d56..451cc0b 100644 (file)
@@ -12,7 +12,7 @@ ERROR: 0:81: 'foo' : no matching overloaded function found
 ERROR: 0:86: '==' :  wrong operand types: no operation '==' exists that takes a left-hand operand of type ' global 4-element array of 7-element array of highp float' and a right operand of type ' global 5-element array of 7-element array of highp float' (or there is no acceptable conversion)
 ERROR: 0:90: '[' :  array index out of range '5'
 ERROR: 0:94: '[' :  index out of range '-1'
-ERROR: 0:96: 'assign' :  cannot convert from ' temp 3-element array of highp 4-component vector of float' to 'layout( column_major shared) buffer unsized 1-element array of highp 4-component vector of float'
+ERROR: 0:96: 'assign' :  cannot convert from ' temp 3-element array of highp 4-component vector of float' to 'layout( column_major shared) buffer unsized 2-element array of highp 4-component vector of float'
 ERROR: 0:103: '' : array size required 
 ERROR: 0:104: '' : array size required 
 ERROR: 0:105: '' : array size required 
@@ -275,9 +275,9 @@ ERROR: node is still EOpNull!
 0:91      Function Call: foo(f1[5][7]; ( global 4-element array of 7-element array of highp float)
 0:91        'u' ( temp 5-element array of 7-element array of highp float)
 0:94      direct index (layout( column_major shared) temp highp 4-component vector of float)
-0:94        v: direct index for structure (layout( column_major shared) buffer unsized 1-element array of highp 4-component vector of float)
-0:94          direct index (layout( column_major shared) temp block{layout( column_major shared) buffer unsized 1-element array of highp float u, layout( column_major shared) buffer unsized 1-element array of highp 4-component vector of float v})
-0:94            'name' (layout( column_major shared) buffer 3-element array of block{layout( column_major shared) buffer unsized 1-element array of highp float u, layout( column_major shared) buffer unsized 1-element array of highp 4-component vector of float v})
+0:94        v: direct index for structure (layout( column_major shared) buffer unsized 2-element array of highp 4-component vector of float)
+0:94          direct index (layout( column_major shared) temp block{layout( column_major shared) buffer unsized 1-element array of highp float u, layout( column_major shared) buffer unsized 2-element array of highp 4-component vector of float v})
+0:94            'name' (layout( column_major shared) buffer 3-element array of block{layout( column_major shared) buffer unsized 1-element array of highp float u, layout( column_major shared) buffer unsized 2-element array of highp 4-component vector of float v})
 0:94            Constant:
 0:94              1 (const int)
 0:94          Constant:
@@ -286,9 +286,9 @@ ERROR: node is still EOpNull!
 0:94          -1 (const int)
 0:95      move second child to first child ( temp highp 4-component vector of float)
 0:95        direct index (layout( column_major shared) temp highp 4-component vector of float)
-0:95          v: direct index for structure (layout( column_major shared) buffer unsized 1-element array of highp 4-component vector of float)
-0:95            direct index (layout( column_major shared) temp block{layout( column_major shared) buffer unsized 1-element array of highp float u, layout( column_major shared) buffer unsized 1-element array of highp 4-component vector of float v})
-0:95              'name' (layout( column_major shared) buffer 3-element array of block{layout( column_major shared) buffer unsized 1-element array of highp float u, layout( column_major shared) buffer unsized 1-element array of highp 4-component vector of float v})
+0:95          v: direct index for structure (layout( column_major shared) buffer unsized 2-element array of highp 4-component vector of float)
+0:95            direct index (layout( column_major shared) temp block{layout( column_major shared) buffer unsized 1-element array of highp float u, layout( column_major shared) buffer unsized 2-element array of highp 4-component vector of float v})
+0:95              'name' (layout( column_major shared) buffer 3-element array of block{layout( column_major shared) buffer unsized 1-element array of highp float u, layout( column_major shared) buffer unsized 2-element array of highp 4-component vector of float v})
 0:95              Constant:
 0:95                1 (const int)
 0:95            Constant:
@@ -300,9 +300,9 @@ ERROR: node is still EOpNull!
 0:95          4.300000
 0:95          4.300000
 0:95          4.300000
-0:96      v: direct index for structure (layout( column_major shared) buffer unsized 1-element array of highp 4-component vector of float)
-0:96        direct index (layout( column_major shared) temp block{layout( column_major shared) buffer unsized 1-element array of highp float u, layout( column_major shared) buffer unsized 1-element array of highp 4-component vector of float v})
-0:96          'name' (layout( column_major shared) buffer 3-element array of block{layout( column_major shared) buffer unsized 1-element array of highp float u, layout( column_major shared) buffer unsized 1-element array of highp 4-component vector of float v})
+0:96      v: direct index for structure (layout( column_major shared) buffer unsized 2-element array of highp 4-component vector of float)
+0:96        direct index (layout( column_major shared) temp block{layout( column_major shared) buffer unsized 1-element array of highp float u, layout( column_major shared) buffer unsized 2-element array of highp 4-component vector of float v})
+0:96          'name' (layout( column_major shared) buffer 3-element array of block{layout( column_major shared) buffer unsized 1-element array of highp float u, layout( column_major shared) buffer unsized 2-element array of highp 4-component vector of float v})
 0:96          Constant:
 0:96            1 (const int)
 0:96        Constant:
@@ -310,9 +310,9 @@ ERROR: node is still EOpNull!
 0:98      Constant:
 0:98        7 (const int)
 0:99      array length ( temp int)
-0:99        v: direct index for structure (layout( column_major shared) buffer unsized 1-element array of 7-element array of highp 4-component vector of float)
-0:99          direct index (layout( column_major shared) temp block{layout( column_major shared) buffer highp float u, layout( column_major shared) buffer unsized 1-element array of 7-element array of highp 4-component vector of float v})
-0:99            'name3' (layout( column_major shared) buffer 3-element array of block{layout( column_major shared) buffer highp float u, layout( column_major shared) buffer unsized 1-element array of 7-element array of highp 4-component vector of float v})
+0:99        v: direct index for structure (layout( column_major shared) buffer unsized 2-element array of 7-element array of highp 4-component vector of float)
+0:99          direct index (layout( column_major shared) temp block{layout( column_major shared) buffer highp float u, layout( column_major shared) buffer unsized 2-element array of 7-element array of highp 4-component vector of float v})
+0:99            'name3' (layout( column_major shared) buffer 3-element array of block{layout( column_major shared) buffer highp float u, layout( column_major shared) buffer unsized 2-element array of 7-element array of highp 4-component vector of float v})
 0:99            Constant:
 0:99              0 (const int)
 0:99          Constant:
@@ -337,10 +337,10 @@ ERROR: node is still EOpNull!
 0:120          Constant:
 0:120            2 (const int)
 0:?   Linker Objects
-0:?     'name' (layout( column_major shared) buffer 3-element array of block{layout( column_major shared) buffer unsized 1-element array of highp float u, layout( column_major shared) buffer unsized 1-element array of highp 4-component vector of float v})
+0:?     'name' (layout( column_major shared) buffer 3-element array of block{layout( column_major shared) buffer unsized 1-element array of highp float u, layout( column_major shared) buffer unsized 2-element array of highp 4-component vector of float v})
 0:?     'uname' (layout( column_major shared) uniform 3-element array of block{layout( column_major shared) uniform highp float u, layout( column_major shared) uniform unsized 1-element array of highp 4-component vector of float v})
 0:?     'name2' (layout( column_major shared) buffer 3-element array of block{layout( column_major shared) buffer highp float u, layout( column_major shared) buffer unsized 1-element array of 1-element array of highp 4-component vector of float v})
-0:?     'name3' (layout( column_major shared) buffer 3-element array of block{layout( column_major shared) buffer highp float u, layout( column_major shared) buffer unsized 1-element array of 7-element array of highp 4-component vector of float v})
+0:?     'name3' (layout( column_major shared) buffer 3-element array of block{layout( column_major shared) buffer highp float u, layout( column_major shared) buffer unsized 2-element array of 7-element array of highp 4-component vector of float v})
 0:?     'many' ( global 1-element array of 2-element array of 3-element array of 4-element array of 5-element array of 6-element array of highp float)
 0:?     'gu' ( global unsized 1-element array of 7-element array of highp float)
 0:?     'g4' ( global 4-element array of 7-element array of highp float)
@@ -378,10 +378,10 @@ ERROR: node is still EOpNull!
 0:13          2 (const uint)
 0:13        'd' ( temp 3-element array of 2-element array of highp int)
 0:?   Linker Objects
-0:?     'name' (layout( column_major shared) buffer 3-element array of block{layout( column_major shared) buffer unsized 1-element array of highp float u, layout( column_major shared) buffer unsized 1-element array of highp 4-component vector of float v})
+0:?     'name' (layout( column_major shared) buffer 3-element array of block{layout( column_major shared) buffer 1-element array of highp float u, layout( column_major shared) buffer unsized 2-element array of highp 4-component vector of float v})
 0:?     'uname' (layout( column_major shared) uniform 3-element array of block{layout( column_major shared) uniform highp float u, layout( column_major shared) uniform 1-element array of highp 4-component vector of float v})
 0:?     'name2' (layout( column_major shared) buffer 3-element array of block{layout( column_major shared) buffer highp float u, layout( column_major shared) buffer unsized 1-element array of 1-element array of highp 4-component vector of float v})
-0:?     'name3' (layout( column_major shared) buffer 3-element array of block{layout( column_major shared) buffer highp float u, layout( column_major shared) buffer unsized 1-element array of 7-element array of highp 4-component vector of float v})
+0:?     'name3' (layout( column_major shared) buffer 3-element array of block{layout( column_major shared) buffer highp float u, layout( column_major shared) buffer unsized 2-element array of 7-element array of highp 4-component vector of float v})
 0:?     'many' ( global 1-element array of 2-element array of 3-element array of 4-element array of 5-element array of 6-element array of highp float)
 0:?     'gu' ( global 1-element array of 7-element array of highp float)
 0:?     'g4' ( global 4-element array of 7-element array of highp float)
index 8898fcc..6975cde 100644 (file)
@@ -11,14 +11,14 @@ ERROR: node is still EOpNull!
 0:7      move second child to first child ( temp highp int)
 0:7        'o' (layout( location=0) smooth out highp int)
 0:7        direct index (layout( column_major shared) temp highp int)
-0:7          a: direct index for structure (layout( column_major shared) uniform unsized 1-element array of highp int)
-0:7            'uni' (layout( binding=0 column_major shared) uniform block{layout( column_major shared) uniform unsized 1-element array of highp int a})
+0:7          a: direct index for structure (layout( column_major shared) uniform unsized 3-element array of highp int)
+0:7            'uni' (layout( binding=0 column_major shared) uniform block{layout( column_major shared) uniform unsized 3-element array of highp int a})
 0:7            Constant:
 0:7              0 (const int)
 0:7          Constant:
 0:7            2 (const int)
 0:?   Linker Objects
-0:?     'uni' (layout( binding=0 column_major shared) uniform block{layout( column_major shared) uniform unsized 1-element array of highp int a})
+0:?     'uni' (layout( binding=0 column_major shared) uniform block{layout( column_major shared) uniform unsized 3-element array of highp int a})
 0:?     'o' (layout( location=0) smooth out highp int)
 0:?     'gl_VertexID' ( gl_VertexId highp int VertexId)
 0:?     'gl_InstanceID' ( gl_InstanceId highp int InstanceId)
@@ -35,14 +35,14 @@ ERROR: node is still EOpNull!
 0:7      move second child to first child ( temp highp int)
 0:7        'o' (layout( location=0) smooth out highp int)
 0:7        direct index (layout( column_major shared) temp highp int)
-0:7          a: direct index for structure (layout( column_major shared) uniform 1-element array of highp int)
-0:7            'uni' (layout( binding=0 column_major shared) uniform block{layout( column_major shared) uniform 1-element array of highp int a})
+0:7          a: direct index for structure (layout( column_major shared) uniform 3-element array of highp int)
+0:7            'uni' (layout( binding=0 column_major shared) uniform block{layout( column_major shared) uniform 3-element array of highp int a})
 0:7            Constant:
 0:7              0 (const int)
 0:7          Constant:
 0:7            2 (const int)
 0:?   Linker Objects
-0:?     'uni' (layout( binding=0 column_major shared) uniform block{layout( column_major shared) uniform 1-element array of highp int a})
+0:?     'uni' (layout( binding=0 column_major shared) uniform block{layout( column_major shared) uniform 3-element array of highp int a})
 0:?     'o' (layout( location=0) smooth out highp int)
 0:?     'gl_VertexID' ( gl_VertexId highp int VertexId)
 0:?     'gl_InstanceID' ( gl_InstanceId highp int InstanceId)
index 7f17400..456bd88 100755 (executable)
@@ -24,7 +24,7 @@ ERROR: 0:49: 'noperspective' : Reserved word.
 ERROR: 0:49: 'noperspective' : not supported for this version or the enabled extensions 
 ERROR: 0:49: 'patch' : cannot use interpolation qualifiers with patch 
 ERROR: 0:50: '' : can only have one auxiliary qualifier (centroid, patch, and sample) 
-ERROR: 0:54: 'gl_PerVertex' : block already declared with size, can't redeclare as implicitly-sized 
+ERROR: 0:54: 'gl_PerVertex' : block already declared with size, can't redeclare as unsized 
 ERROR: 0:59: 'gl_PerVertex' : can only redeclare a built-in block once, and before any use 
 ERROR: 0:64: 'quads' : cannot apply to 'out' 
 ERROR: 0:64: 'cw' : can only apply to 'in' 
index 01db283..28c4468 100644 (file)
@@ -11,7 +11,7 @@ ERROR: 0:47: 'patch' : cannot use interpolation qualifiers with patch
 ERROR: 0:48: 'patch' : cannot use interpolation qualifiers with patch 
 ERROR: 0:49: 'patch' : cannot use interpolation qualifiers with patch 
 ERROR: 0:50: '' : can only have one auxiliary qualifier (centroid, patch, and sample) 
-ERROR: 0:54: 'gl_PerVertex' : block already declared with size, can't redeclare as implicitly-sized 
+ERROR: 0:54: 'gl_PerVertex' : block already declared with size, can't redeclare as unsized 
 ERROR: 0:59: 'gl_PerVertex' : can only redeclare a built-in block once, and before any use 
 ERROR: 0:64: 'quads' : cannot apply to 'out' 
 ERROR: 0:64: 'cw' : can only apply to 'in' 
index 85e15c5..4fa8516 100644 (file)
@@ -51,7 +51,7 @@ ERROR: 0:157: 'textureQueryLevels' : no matching overloaded function found
 ERROR: 0:157: 'assign' :  cannot convert from ' const float' to ' temp int'
 ERROR: 0:158: 'textureQueryLevels' : no matching overloaded function found 
 ERROR: 0:158: 'assign' :  cannot convert from ' const float' to ' temp int'
-WARNING: 0:161: '[]' : assuming array size of one for compile-time checking of binding numbers for implicitly-sized array 
+WARNING: 0:161: '[]' : assuming array size of one for compile-time checking of binding numbers for unsized array 
 ERROR: 51 compilation errors.  No code generated.
 
 
index 654b3e2..599cd8e 100644 (file)
@@ -33,13 +33,13 @@ ERROR: node is still EOpNull!
 0:35      GroupMemoryBarrier ( global void)
 0:36      move second child to first child ( temp int)
 0:36        value: direct index for structure (layout( column_major shared) buffer int)
-0:36          'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer int value, layout( column_major shared) buffer unsized 1-element array of float values})
+0:36          'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer int value, layout( column_major shared) buffer runtime-sized array of float values})
 0:36          Constant:
 0:36            0 (const uint)
 0:36        Convert float to int ( temp int)
 0:36          indirect index (layout( column_major shared) temp float)
-0:36            values: direct index for structure (layout( column_major shared) buffer unsized 1-element array of float)
-0:36              'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer int value, layout( column_major shared) buffer unsized 1-element array of float values})
+0:36            values: direct index for structure (layout( column_major shared) buffer runtime-sized array of float)
+0:36              'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer int value, layout( column_major shared) buffer runtime-sized array of float values})
 0:36              Constant:
 0:36                1 (const uint)
 0:36            'gl_LocalInvocationIndex' ( in uint LocalInvocationIndex)
@@ -56,8 +56,8 @@ ERROR: node is still EOpNull!
 0:65    Sequence
 0:65      move second child to first child ( temp float)
 0:65        direct index (layout( column_major shared) temp float)
-0:65          values: direct index for structure (layout( column_major shared) buffer unsized 1-element array of float)
-0:65            'ro' (layout( column_major shared) readonly buffer block{layout( column_major shared) buffer int value, layout( column_major shared) buffer unsized 1-element array of float values})
+0:65          values: direct index for structure (layout( column_major shared) buffer unsized 3-element array of float)
+0:65            'ro' (layout( column_major shared) readonly buffer block{layout( column_major shared) buffer int value, layout( column_major shared) buffer unsized 3-element array of float values})
 0:65            Constant:
 0:65              1 (const int)
 0:65          Constant:
@@ -65,8 +65,8 @@ ERROR: node is still EOpNull!
 0:65        Constant:
 0:65          4.700000
 0:66      array length ( temp int)
-0:66        values: direct index for structure (layout( column_major shared) buffer unsized 1-element array of float)
-0:66          'ro' (layout( column_major shared) readonly buffer block{layout( column_major shared) buffer int value, layout( column_major shared) buffer unsized 1-element array of float values})
+0:66        values: direct index for structure (layout( column_major shared) buffer unsized 3-element array of float)
+0:66          'ro' (layout( column_major shared) readonly buffer block{layout( column_major shared) buffer int value, layout( column_major shared) buffer unsized 3-element array of float values})
 0:66          Constant:
 0:66            1 (const int)
 0:67      Barrier ( global void)
@@ -129,7 +129,7 @@ ERROR: node is still EOpNull!
 0:?       4096 (const uint)
 0:?     'total' ( const int)
 0:?       66592 (const int)
-0:?     'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer int value, layout( column_major shared) buffer unsized 1-element array of float values})
+0:?     'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer int value, layout( column_major shared) buffer runtime-sized array of float values})
 0:?     'invalid' (layout( column_major shared) buffer block{layout( column_major shared) buffer unsized 1-element array of float values, layout( column_major shared) buffer int value})
 0:?     'v3' (layout( location=2) in 3-component vector of float)
 0:?     'f' ( in float)
@@ -140,7 +140,7 @@ ERROR: node is still EOpNull!
 0:?     'arrX' ( global 2-element array of int)
 0:?     'arrY' ( global 1-element array of int)
 0:?     'arrZ' ( global 4096-element array of int)
-0:?     'ro' (layout( column_major shared) readonly buffer block{layout( column_major shared) buffer int value, layout( column_major shared) buffer unsized 1-element array of float values})
+0:?     'ro' (layout( column_major shared) readonly buffer block{layout( column_major shared) buffer int value, layout( column_major shared) buffer unsized 3-element array of float values})
 0:?     'roll' ( uniform double)
 0:?     'destTex' ( writeonly uniform image2D)
 0:?     'inbi' ( in block{ in int a})
@@ -165,13 +165,13 @@ ERROR: node is still EOpNull!
 0:35      GroupMemoryBarrier ( global void)
 0:36      move second child to first child ( temp int)
 0:36        value: direct index for structure (layout( column_major shared) buffer int)
-0:36          'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer int value, layout( column_major shared) buffer unsized 1-element array of float values})
+0:36          'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer int value, layout( column_major shared) buffer runtime-sized array of float values})
 0:36          Constant:
 0:36            0 (const uint)
 0:36        Convert float to int ( temp int)
 0:36          indirect index (layout( column_major shared) temp float)
-0:36            values: direct index for structure (layout( column_major shared) buffer unsized 1-element array of float)
-0:36              'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer int value, layout( column_major shared) buffer unsized 1-element array of float values})
+0:36            values: direct index for structure (layout( column_major shared) buffer runtime-sized array of float)
+0:36              'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer int value, layout( column_major shared) buffer runtime-sized array of float values})
 0:36              Constant:
 0:36                1 (const uint)
 0:36            'gl_LocalInvocationIndex' ( in uint LocalInvocationIndex)
@@ -190,8 +190,8 @@ ERROR: node is still EOpNull!
 0:?       4096 (const uint)
 0:?     'total' ( const int)
 0:?       66592 (const int)
-0:?     'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer int value, layout( column_major shared) buffer unsized 1-element array of float values})
-0:?     'invalid' (layout( column_major shared) buffer block{layout( column_major shared) buffer unsized 1-element array of float values, layout( column_major shared) buffer int value})
+0:?     'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer int value, layout( column_major shared) buffer runtime-sized array of float values})
+0:?     'invalid' (layout( column_major shared) buffer block{layout( column_major shared) buffer 1-element array of float values, layout( column_major shared) buffer int value})
 0:?     'v3' (layout( location=2) in 3-component vector of float)
 0:?     'f' ( in float)
 0:?     'fo' ( out float)
@@ -201,7 +201,7 @@ ERROR: node is still EOpNull!
 0:?     'arrX' ( global 2-element array of int)
 0:?     'arrY' ( global 1-element array of int)
 0:?     'arrZ' ( global 4096-element array of int)
-0:?     'ro' (layout( column_major shared) readonly buffer block{layout( column_major shared) buffer int value, layout( column_major shared) buffer unsized 1-element array of float values})
+0:?     'ro' (layout( column_major shared) readonly buffer block{layout( column_major shared) buffer int value, layout( column_major shared) buffer unsized 3-element array of float values})
 0:?     'roll' ( uniform double)
 0:?     'destTex' ( writeonly uniform image2D)
 0:?     'inbi' ( in block{ in int a})
index b3bcec3..9f50b4f 100644 (file)
@@ -2,7 +2,7 @@ array.frag
 ERROR: 0:21: '[' :  array index out of range '2'
 ERROR: 0:27: '[' :  array must be redeclared with a size before being indexed with a variable
 ERROR: 0:30: 'assign' :  cannot convert from ' global 4-element array of float' to ' global 5-element array of float'
-ERROR: 0:31: 'assign' :  cannot convert from ' global 4-element array of float' to ' global unsized 4-element array of float'
+ERROR: 0:31: 'assign' :  cannot convert from ' global 4-element array of float' to ' global runtime-sized array of float'
 ERROR: 0:33: 'foo' : no matching overloaded function found 
 ERROR: 0:42: '[' :  array index out of range '5'
 ERROR: 0:45: '[' :  array index out of range '1000'
@@ -25,7 +25,9 @@ ERROR: 0:101: '[' :  array index out of range '5'
 ERROR: 0:104: 'constructor' : array constructor must have at least one argument 
 ERROR: 0:104: '=' :  cannot convert from ' const float' to ' global unsized 1-element array of int'
 ERROR: 0:106: 'constructor' : array argument must be sized 
-ERROR: 26 compilation errors.  No code generated.
+ERROR: 0:111: '[' :  array must be redeclared with a size before being indexed with a variable
+ERROR: 0:111: 'variable indexing sampler array' : not supported with this profile: none
+ERROR: 28 compilation errors.  No code generated.
 
 
 Shader version: 130
@@ -68,21 +70,21 @@ ERROR: node is still EOpNull!
 0:21            4.000000
 0:24      move second child to first child ( temp float)
 0:24        direct index ( temp float)
-0:24          'gu' ( global unsized 4-element array of float)
+0:24          'gu' ( global runtime-sized array of float)
 0:24          Constant:
 0:24            2 (const int)
 0:24        Constant:
 0:24          4.000000
 0:26      move second child to first child ( temp float)
 0:26        direct index ( temp float)
-0:26          'gu' ( global unsized 4-element array of float)
+0:26          'gu' ( global runtime-sized array of float)
 0:26          Constant:
 0:26            3 (const int)
 0:26        Constant:
 0:26          3.000000
 0:27      move second child to first child ( temp float)
 0:27        indirect index ( temp float)
-0:27          'gu' ( global unsized 4-element array of float)
+0:27          'gu' ( global runtime-sized array of float)
 0:27          'a' ( uniform int)
 0:27        Constant:
 0:27          5.000000
@@ -91,7 +93,7 @@ ERROR: node is still EOpNull!
 0:29        Function Call: foo(f1[5]; ( global 4-element array of float)
 0:29          'g5' ( global 5-element array of float)
 0:30      'g5' ( global 5-element array of float)
-0:31      'gu' ( global unsized 4-element array of float)
+0:31      'gu' ( global runtime-sized array of float)
 0:33      Constant:
 0:33        0.000000
 0:34      Function Call: bar(f1[5]; ( global void)
@@ -108,7 +110,7 @@ ERROR: node is still EOpNull!
 0:36        true case
 0:37        move second child to first child ( temp float)
 0:37          direct index ( temp float)
-0:37            'gu' ( global unsized 4-element array of float)
+0:37            'gu' ( global runtime-sized array of float)
 0:37            Constant:
 0:37              0 (const int)
 0:37          Constant:
@@ -264,8 +266,14 @@ ERROR: node is still EOpNull!
 0:106      'b' ( global float)
 0:106      Constant:
 0:106        0.000000
+0:109  Function Definition: foo4( ( global void)
+0:109    Function Parameters: 
+0:111    Sequence
+0:111      indirect index ( temp sampler2D)
+0:111        's2d' ( uniform runtime-sized array of sampler2D)
+0:111        'a' ( uniform int)
 0:?   Linker Objects
-0:?     'gu' ( global unsized 4-element array of float)
+0:?     'gu' ( global runtime-sized array of float)
 0:?     'g4' ( global 4-element array of float)
 0:?     'g5' ( global 5-element array of float)
 0:?     'a' ( uniform int)
@@ -275,6 +283,7 @@ ERROR: node is still EOpNull!
 0:?     'i' ( global unsized 1-element array of int)
 0:?     'emptyA' ( global unsized 1-element array of float)
 0:?     'b' ( global float)
+0:?     's2d' ( uniform runtime-sized array of sampler2D)
 
 
 Linked fragment stage:
@@ -320,21 +329,21 @@ ERROR: node is still EOpNull!
 0:21            4.000000
 0:24      move second child to first child ( temp float)
 0:24        direct index ( temp float)
-0:24          'gu' ( global 4-element array of float)
+0:24          'gu' ( global runtime-sized array of float)
 0:24          Constant:
 0:24            2 (const int)
 0:24        Constant:
 0:24          4.000000
 0:26      move second child to first child ( temp float)
 0:26        direct index ( temp float)
-0:26          'gu' ( global 4-element array of float)
+0:26          'gu' ( global runtime-sized array of float)
 0:26          Constant:
 0:26            3 (const int)
 0:26        Constant:
 0:26          3.000000
 0:27      move second child to first child ( temp float)
 0:27        indirect index ( temp float)
-0:27          'gu' ( global 4-element array of float)
+0:27          'gu' ( global runtime-sized array of float)
 0:27          'a' ( uniform int)
 0:27        Constant:
 0:27          5.000000
@@ -343,7 +352,7 @@ ERROR: node is still EOpNull!
 0:29        Function Call: foo(f1[5]; ( global 4-element array of float)
 0:29          'g5' ( global 5-element array of float)
 0:30      'g5' ( global 5-element array of float)
-0:31      'gu' ( global 4-element array of float)
+0:31      'gu' ( global runtime-sized array of float)
 0:33      Constant:
 0:33        0.000000
 0:34      Function Call: bar(f1[5]; ( global void)
@@ -360,7 +369,7 @@ ERROR: node is still EOpNull!
 0:36        true case
 0:37        move second child to first child ( temp float)
 0:37          direct index ( temp float)
-0:37            'gu' ( global 4-element array of float)
+0:37            'gu' ( global runtime-sized array of float)
 0:37            Constant:
 0:37              0 (const int)
 0:37          Constant:
@@ -452,7 +461,7 @@ ERROR: node is still EOpNull!
 0:106      Constant:
 0:106        0.000000
 0:?   Linker Objects
-0:?     'gu' ( global 4-element array of float)
+0:?     'gu' ( global runtime-sized array of float)
 0:?     'g4' ( global 4-element array of float)
 0:?     'g5' ( global 5-element array of float)
 0:?     'a' ( uniform int)
@@ -462,4 +471,5 @@ ERROR: node is still EOpNull!
 0:?     'i' ( global 1-element array of int)
 0:?     'emptyA' ( global 1-element array of float)
 0:?     'b' ( global float)
+0:?     's2d' ( uniform runtime-sized array of sampler2D)
 
index 7ed8a6b..03f3c34 100644 (file)
@@ -470,7 +470,7 @@ public:
     // Drop just the storage qualification, which perhaps should
     // never be done, as it is fundamentally inconsistent, but need to
     // explore what downstream consumers need.
-    // E.g., in a deference, it is an inconsistency between:
+    // E.g., in a dereference, it is an inconsistency between:
     // A) partially dereferenced resource is still in the storage class it started in
     // B) partially dereferenced resource is a new temporary object
     // If A, then nothing should change, if B, then everything should change, but this is half way.
@@ -1354,9 +1354,11 @@ public:
     virtual bool isVector() const { return vectorSize > 1 || vector1; }
     virtual bool isMatrix() const { return matrixCols ? true : false; }
     virtual bool isArray()  const { return arraySizes != nullptr; }
-    virtual bool isExplicitlySizedArray() const { return isArray() && getOuterArraySize() != UnsizedArraySize; }
-    virtual bool isImplicitlySizedArray() const { return isArray() && getOuterArraySize() == UnsizedArraySize && qualifier.storage != EvqBuffer; }
-    virtual bool isRuntimeSizedArray()    const { return isArray() && getOuterArraySize() == UnsizedArraySize && qualifier.storage == EvqBuffer; }
+    virtual bool isSizedArray() const { return isArray() && arraySizes->isSized(); }
+    virtual bool isUnsizedArray() const { return isArray() && !arraySizes->isSized(); }
+    virtual bool isArrayVariablyIndexed() const { assert(isArray()); return arraySizes->isVariablyIndexed(); }
+    virtual void setArrayVariablyIndexed() { assert(isArray()); arraySizes->setVariablyIndexed(); }
+    virtual void updateImplicitArraySize(int size) { assert(isArray()); arraySizes->updateImplicitSize(size); }
     virtual bool isStruct() const { return structure != nullptr; }
     virtual bool isFloatingDomain() const { return basicType == EbtFloat || basicType == EbtDouble || basicType == EbtFloat16; }
     virtual bool isIntegerDomain() const
@@ -1414,10 +1416,10 @@ public:
         return contains([this](const TType* t) { return t != this && t->isStruct(); } );
     }
 
-    // Recursively check the structure for any implicitly-sized arrays, needed for triggering a copyUp().
-    virtual bool containsImplicitlySizedArray() const
+    // Recursively check the structure for any unsized arrays, needed for triggering a copyUp().
+    virtual bool containsUnsizedArray() const
     {
-        return contains([](const TType* t) { return t->isImplicitlySizedArray(); } );
+        return contains([](const TType* t) { return t->isUnsizedArray(); } );
     }
 
     virtual bool containsOpaque() const
@@ -1510,16 +1512,22 @@ public:
         }
     }
     void changeOuterArraySize(int s) { arraySizes->changeOuterSize(s); }
-    void setImplicitArraySize(int s) { arraySizes->setImplicitSize(s); }
 
-    // Recursively make the implicit array size the explicit array size, through the type tree.
-    void adoptImplicitArraySizes()
+    // Recursively make the implicit array size the explicit array size.
+    // Expicit arrays are compile-time or link-time sized, never run-time sized.
+    // Sometimes, policy calls for an array to be run-time sized even if it was
+    // never variably indexed: Don't turn a 'skipNonvariablyIndexed' array into
+    // an explicit array.
+    void adoptImplicitArraySizes(bool skipNonvariablyIndexed)
     {
-        if (isImplicitlySizedArray())
+        if (isUnsizedArray() && !(skipNonvariablyIndexed || isArrayVariablyIndexed()))
             changeOuterArraySize(getImplicitArraySize());
-        if (isStruct()) {
-            for (int i = 0; i < (int)structure->size(); ++i)
-                (*structure)[i].type->adoptImplicitArraySizes();
+        if (isStruct() && structure->size() > 0) {
+            int lastMember = (int)structure->size() - 1;
+            for (int i = 0; i < lastMember; ++i)
+                (*structure)[i].type->adoptImplicitArraySizes(false);
+            // implement the "last member of an SSBO" policy
+            (*structure)[lastMember].type->adoptImplicitArraySizes(getQualifier().storage == EvqBuffer);
         }
     }
 
@@ -1686,17 +1694,21 @@ public:
         if (isArray()) {
             for(int i = 0; i < (int)arraySizes->getNumDims(); ++i) {
                 int size = arraySizes->getDimSize(i);
-                if (size == UnsizedArraySize) {
-                    appendStr(" unsized");
-                    if (i == 0) {
+                if (size == UnsizedArraySize && i == 0 && arraySizes->isVariablyIndexed())
+                    appendStr(" runtime-sized array of");
+                else {
+                    if (size == UnsizedArraySize) {
+                        appendStr(" unsized");
+                        if (i == 0) {
+                            appendStr(" ");
+                            appendInt(arraySizes->getImplicitSize());
+                        }
+                    } else {
                         appendStr(" ");
-                        appendInt(arraySizes->getImplicitSize());
+                        appendInt(arraySizes->getDimSize(i));
                     }
-                } else {
-                    appendStr(" ");
-                    appendInt(arraySizes->getDimSize(i));
+                    appendStr("-element array of");
                 }
-                appendStr("-element array of");
             }
         }
         if (qualifier.precision != EpqNone) {
index d7fe8a1..af8f560 100644 (file)
@@ -41,6 +41,8 @@
 #ifndef _ARRAYS_INCLUDED
 #define _ARRAYS_INCLUDED
 
+#include <algorithm>
+
 namespace glslang {
 
 // This is used to mean there is no size yet (unsized), it is waiting to get a size from somewhere else.
@@ -220,12 +222,13 @@ protected:
 struct TArraySizes {
     POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
 
-    TArraySizes() : implicitArraySize(1) { }
+    TArraySizes() : implicitArraySize(1), variablyIndexed(false) { }
 
     // For breaking into two non-shared copies, independently modifiable.
     TArraySizes& operator=(const TArraySizes& from)
     {
         implicitArraySize = from.implicitArraySize;
+        variablyIndexed = from.variablyIndexed;
         sizes = from.sizes;
 
         return *this;
@@ -254,9 +257,9 @@ struct TArraySizes {
     void addInnerSize(TArraySize pair) { sizes.push_back(pair.size, pair.node); }
     void addInnerSizes(const TArraySizes& s) { sizes.push_back(s.sizes); }
     void changeOuterSize(int s) { sizes.changeFront((unsigned)s); }
-    int getImplicitSize() const { return (int)implicitArraySize; }
-    void setImplicitSize(int s) { implicitArraySize = s; }
-    bool isInnerImplicit() const
+    int getImplicitSize() const { return implicitArraySize; }
+    void updateImplicitSize(int s) { implicitArraySize = std::max(implicitArraySize, s); }
+    bool isInnerUnsized() const
     {
         for (int d = 1; d < sizes.size(); ++d) {
             if (sizes.getDimSize(d) == (unsigned)UnsizedArraySize)
@@ -265,7 +268,7 @@ struct TArraySizes {
 
         return false;
     }
-    bool clearInnerImplicit()
+    bool clearInnerUnsized()
     {
         for (int d = 1; d < sizes.size(); ++d) {
             if (sizes.getDimSize(d) == (unsigned)UnsizedArraySize)
@@ -288,7 +291,8 @@ struct TArraySizes {
         return sizes.getDimNode(0) != nullptr;
     }
 
-    bool isImplicit() const { return getOuterSize() == UnsizedArraySize || isInnerImplicit(); }
+    bool hasUnsized() const { return getOuterSize() == UnsizedArraySize || isInnerUnsized(); }
+    bool isSized() const { return getOuterSize() != UnsizedArraySize; }
     void dereference() { sizes.pop_front(); }
     void copyDereferenced(const TArraySizes& rhs)
     {
@@ -311,6 +315,9 @@ struct TArraySizes {
         return true;
     }
 
+    void setVariablyIndexed() { variablyIndexed = true; }
+    bool isVariablyIndexed() const { return variablyIndexed; }
+
     bool operator==(const TArraySizes& rhs) { return sizes == rhs.sizes; }
     bool operator!=(const TArraySizes& rhs) { return sizes != rhs.sizes; }
 
@@ -319,9 +326,12 @@ protected:
 
     TArraySizes(const TArraySizes&);
 
-    // for tracking maximum referenced index, before an explicit size is given
-    // applies only to the outer-most dimension
+    // For tracking maximum referenced compile-time constant index.
+    // Applies only to the outer-most dimension. Potentially becomes
+    // the implicit size of the array, if not variably indexed and
+    // otherwise legal.
     int implicitArraySize;
+    bool variablyIndexed;  // true if array is indexed with a non compile-time constant
 };
 
 } // end namespace glslang
index b4e4858..935fc2c 100644 (file)
@@ -729,7 +729,11 @@ enum TOperator {
     // Array operators
     //
 
-    EOpArrayLength,      // "Array" distinguishes from length(v) built-in function, but it applies to vectors and matrices as well.
+    // Can apply to arrays, vectors, or matrices.
+    // Can be decomposed to a constant at compile time, but this does not always happen,
+    // due to link-time effects. So, consumer can expect either a link-time sized or
+    // run-time sized array.
+    EOpArrayLength,
 
     //
     // Image operations
index 525ed4e..bfa9de4 100644 (file)
@@ -243,7 +243,7 @@ void TParseContextBase::checkIndex(const TSourceLoc& loc, const TType& type, int
         error(loc, "", "[", "index out of range '%d'", index);
         index = 0;
     } else if (type.isArray()) {
-        if (type.isExplicitlySizedArray() && index >= type.getOuterArraySize()) {
+        if (type.isSizedArray() && index >= type.getOuterArraySize()) {
             error(loc, "", "[", "array index out of range '%d'", index);
             index = type.getOuterArraySize() - 1;
         }
index eb71ad5..06ca489 100644 (file)
@@ -284,17 +284,17 @@ TIntermTyped* TParseContext::handleVariable(const TSourceLoc& loc, TSymbol* symb
         requireExtensions(loc, symbol->getNumExtensions(), symbol->getExtensions(), symbol->getName().c_str());
 
     if (symbol && symbol->isReadOnly()) {
-        // All shared things containing an implicitly sized array must be copied up
+        // All shared things containing an unsized array must be copied up
         // on first use, so that all future references will share its array structure,
         // so that editing the implicit size will effect all nodes consuming it,
         // and so that editing the implicit size won't change the shared one.
         //
         // If this is a variable or a block, check it and all it contains, but if this
         // is a member of an anonymous block, check the whole block, as the whole block
-        // will need to be copied up if it contains an implicitly-sized array.
-        if (symbol->getType().containsImplicitlySizedArray() ||
+        // will need to be copied up if it contains an unsized array.
+        if (symbol->getType().containsUnsizedArray() ||
             (symbol->getAsAnonMember() &&
-             symbol->getAsAnonMember()->getAnonContainer().getType().containsImplicitlySizedArray()))
+             symbol->getAsAnonMember()->getAnonContainer().getType().containsUnsizedArray()))
             makeEditable(symbol);
     }
 
@@ -372,21 +372,28 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn
     } else {
         // at least one of base and index is not a front-end constant variable...
 
+        if (index->getQualifier().isFrontEndConstant())
+            checkIndex(loc, base->getType(), indexValue);
+
         if (base->getAsSymbolNode() && isIoResizeArray(base->getType()))
             handleIoResizeArrayAccess(loc, base);
 
         if (index->getQualifier().isFrontEndConstant()) {
-            if (base->getType().isImplicitlySizedArray())
-                updateImplicitArraySize(loc, base, indexValue);
-            else
-                checkIndex(loc, base->getType(), indexValue);
+            if (base->getType().isUnsizedArray())
+                base->getWritableType().updateImplicitArraySize(indexValue + 1);
             result = intermediate.addIndex(EOpIndexDirect, base, index, loc);
         } else {
-            if (base->getType().isImplicitlySizedArray()) {
+            if (base->getType().isUnsizedArray()) {
+                // we have a variable index into an unsized array, which is okay,
+                // depending on the situation
                 if (base->getAsSymbolNode() && isIoResizeArray(base->getType()))
                     error(loc, "", "[", "array must be sized by a redeclaration or layout qualifier before being indexed with a variable");
-                else
-                    error(loc, "", "[", "array must be redeclared with a size before being indexed with a variable");
+                else {
+                    // it is okay for a run-time sized array
+                    if (base->getType().getQualifier().storage != EvqBuffer)
+                        error(loc, "", "[", "array must be redeclared with a size before being indexed with a variable");
+                }
+                base->getWritableType().setArrayVariablyIndexed();
             }
             if (base->getBasicType() == EbtBlock) {
                 if (base->getQualifier().storage == EvqBuffer)
@@ -485,7 +492,7 @@ void TParseContext::fixIoArraySize(const TSourceLoc& loc, TType& type)
 
     if (language == EShLangTessControl || language == EShLangTessEvaluation) {
         if (type.getOuterArraySize() != resources.maxPatchVertices) {
-            if (type.isExplicitlySizedArray())
+            if (type.isSizedArray())
                 error(loc, "tessellation input array size must be gl_MaxPatchVertices or implicitly sized", "[]", "");
             type.changeOuterArraySize(resources.maxPatchVertices);
         }
@@ -518,7 +525,7 @@ void TParseContext::handleIoResizeArrayAccess(const TSourceLoc& /*loc*/, TInterm
         return;
 
     // fix array size, if it can be fixed and needs to be fixed (will allow variable indexing)
-    if (symbolNode->getType().isImplicitlySizedArray()) {
+    if (symbolNode->getType().isUnsizedArray()) {
         int newSize = getIoArrayImplicitSize();
         if (newSize > 0)
             symbolNode->getWritableType().changeOuterArraySize(newSize);
@@ -568,7 +575,7 @@ int TParseContext::getIoArrayImplicitSize() const
 
 void TParseContext::checkIoArrayConsistency(const TSourceLoc& loc, int requiredSize, const char* feature, TType& type, const TString& name)
 {
-    if (type.isImplicitlySizedArray())
+    if (type.isUnsizedArray())
         type.changeOuterArraySize(requiredSize);
     else if (type.getOuterArraySize() != requiredSize) {
         if (language == EShLangGeometry)
@@ -1215,10 +1222,7 @@ TIntermTyped* TParseContext::handleLengthMethod(const TSourceLoc& loc, TFunction
     else {
         const TType& type = intermNode->getAsTyped()->getType();
         if (type.isArray()) {
-            if (type.isRuntimeSizedArray()) {
-                // Create a unary op and let the back end handle it
-                return intermediate.addBuiltInFunctionCall(loc, EOpArrayLength, true, intermNode, TType(EbtInt));
-            } else if (type.isImplicitlySizedArray()) {
+            if (type.isUnsizedArray()) {
                 if (intermNode->getAsSymbolNode() && isIoResizeArray(type)) {
                     // We could be between a layout declaration that gives a built-in io array implicit size and
                     // a user redeclaration of that array, meaning we have to substitute its implicit size here
@@ -1231,7 +1235,10 @@ TIntermTyped* TParseContext::handleLengthMethod(const TSourceLoc& loc, TFunction
                 if (length == 0) {
                     if (intermNode->getAsSymbolNode() && isIoResizeArray(type))
                         error(loc, "", function->getName().c_str(), "array must first be sized by a redeclaration or layout qualifier");
-                    else
+                    else if (type.getQualifier().isUniformOrBuffer()) {
+                        // Create a unary op and let the back end handle it
+                        return intermediate.addBuiltInFunctionCall(loc, EOpArrayLength, true, intermNode, TType(EbtInt));
+                    } else
                         error(loc, "", function->getName().c_str(), "array must be declared with a size before using this method");
                 }
             } else if (type.getOuterArrayNode()) {
@@ -2283,7 +2290,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
     bool floatArgument = false;
     for (int arg = 0; arg < function.getParamCount(); ++arg) {
         if (function[arg].type->isArray()) {
-            if (! function[arg].type->isExplicitlySizedArray()) {
+            if (function[arg].type->isUnsizedArray()) {
                 // Can't construct from an unsized array.
                 error(loc, "array argument must be sized", "constructor", "");
                 return true;
@@ -2381,7 +2388,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
             return true;
         }
 
-        if (type.isImplicitlySizedArray()) {
+        if (type.isUnsizedArray()) {
             // auto adapt the constructor type to the number of arguments
             type.changeOuterArraySize(function.getParamCount());
         } else if (type.getOuterArraySize() != function.getParamCount()) {
@@ -2402,7 +2409,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
                 return true;
             }
 
-            if (arraySizes.isInnerImplicit()) {
+            if (arraySizes.isInnerUnsized()) {
                 // "Arrays of arrays ..., and the size for any dimension is optional"
                 // That means we need to adopt (from the first argument) the other array sizes into the type.
                 for (int d = 1; d < arraySizes.getNumDims(); ++d) {
@@ -2609,6 +2616,15 @@ void TParseContext::transparentOpaqueCheck(const TSourceLoc& loc, const TType& t
 }
 
 //
+// Qualifier checks knowing the qualifier and that it is a member of a struct/block.
+//
+void TParseContext::memberQualifierCheck(glslang::TPublicType& publicType)
+{
+    globalQualifierFixCheck(publicType.loc, publicType.qualifier);
+    checkNoShaderLayouts(publicType.loc, publicType.shaderQualifiers);
+}
+
+//
 // Check/fix just a full qualifier (no variables or types yet, but qualifier is complete) at global level.
 //
 void TParseContext::globalQualifierFixCheck(const TSourceLoc& loc, TQualifier& qualifier)
@@ -3081,7 +3097,7 @@ bool TParseContext::arrayError(const TSourceLoc& loc, const TType& type)
 //
 void TParseContext::arraySizeRequiredCheck(const TSourceLoc& loc, const TArraySizes& arraySizes)
 {
-    if (arraySizes.isImplicit())
+    if (arraySizes.hasUnsized())
         error(loc, "array size required", "", "");
 }
 
@@ -3108,9 +3124,9 @@ void TParseContext::arraySizesCheck(const TSourceLoc& loc, const TQualifier& qua
         return;
 
     // No environment allows any non-outer-dimension to be implicitly sized
-    if (arraySizes->isInnerImplicit()) {
+    if (arraySizes->isInnerUnsized()) {
         error(loc, "only outermost dimension of an array of arrays can be implicitly sized", "[]", "");
-        arraySizes->clearInnerImplicit();
+        arraySizes->clearInnerUnsized();
     }
 
     if (arraySizes->isInnerSpecialization())
@@ -3237,7 +3253,7 @@ void TParseContext::declareArray(const TSourceLoc& loc, const TString& identifie
         return;
     }
 
-    if (existingType.isExplicitlySizedArray()) {
+    if (existingType.isSizedArray()) {
         // be more leniant for input arrays to geometry shaders and tessellation control outputs, where the redeclaration is the same size
         if (! (isIoResizeArray(type) && existingType.getOuterArraySize() == type.getOuterArraySize()))
             error(loc, "redeclaration of array with size", identifier.c_str(), "");
@@ -3252,66 +3268,6 @@ void TParseContext::declareArray(const TSourceLoc& loc, const TString& identifie
         checkIoArraysConsistency(loc);
 }
 
-void TParseContext::updateImplicitArraySize(const TSourceLoc& loc, TIntermNode *node, int index)
-{
-    // maybe there is nothing to do...
-    TIntermTyped* typedNode = node->getAsTyped();
-    if (typedNode->getType().getImplicitArraySize() > index)
-        return;
-
-    // something to do...
-
-    // Figure out what symbol to lookup, as we will use its type to edit for the size change,
-    // as that type will be shared through shallow copies for future references.
-    TSymbol* symbol = nullptr;
-    int blockIndex = -1;
-    const TString* lookupName = nullptr;
-    if (node->getAsSymbolNode())
-        lookupName = &node->getAsSymbolNode()->getName();
-    else if (node->getAsBinaryNode()) {
-        const TIntermBinary* deref = node->getAsBinaryNode();
-        // This has to be the result of a block dereference, unless it's bad shader code
-        // If it's a uniform block, then an error will be issued elsewhere, but
-        // return early now to avoid crashing later in this function.
-        if (deref->getLeft()->getBasicType() != EbtBlock ||
-            deref->getLeft()->getType().getQualifier().storage == EvqUniform ||
-            deref->getRight()->getAsConstantUnion() == nullptr)
-            return;
-
-        const TIntermTyped* left  = deref->getLeft();
-        const TIntermTyped* right = deref->getRight();
-
-        if (left->getAsBinaryNode()) {
-            left = left->getAsBinaryNode()->getLeft(); // Block array access
-            assert(left->isArray());
-        }
-
-        if (! left->getAsSymbolNode())
-            return;
-
-        blockIndex = right->getAsConstantUnion()->getConstArray()[0].getIConst();
-
-        lookupName = &left->getAsSymbolNode()->getName();
-        if (IsAnonymous(*lookupName))
-            lookupName = &(*left->getType().getStruct())[blockIndex].type->getFieldName();
-    }
-
-    // Lookup the symbol, should only fail if shader code is incorrect
-    symbol = symbolTable.find(*lookupName);
-    if (symbol == nullptr)
-        return;
-
-    if (symbol->getAsFunction()) {
-        error(loc, "array variable name expected", symbol->getName().c_str(), "");
-        return;
-    }
-
-    if (symbol->getType().isStruct() && blockIndex != -1)
-        (*symbol->getWritableType().getStruct())[blockIndex].type->setImplicitArraySize(index + 1);
-    else
-        symbol->getWritableType().setImplicitArraySize(index + 1);
-}
-
 // Returns true if the first argument to the #line directive is the line number for the next line.
 //
 // Desktop, pre-version 3.30:  "After processing this directive
@@ -3597,7 +3553,7 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT
                 error(memberLoc, "cannot redeclare block member with a different type", member->type->getFieldName().c_str(), "");
             if (oldType.isArray() != newType.isArray())
                 error(memberLoc, "cannot change arrayness of redeclared block member", member->type->getFieldName().c_str(), "");
-            else if (! oldType.sameArrayness(newType) && oldType.isExplicitlySizedArray())
+            else if (! oldType.sameArrayness(newType) && oldType.isSizedArray())
                 error(memberLoc, "cannot change array size of redeclared block member", member->type->getFieldName().c_str(), "");
             else if (newType.isArray())
                 arrayLimitCheck(loc, member->type->getFieldName(), newType.getOuterArraySize());
@@ -3626,7 +3582,7 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT
                 type.getQualifier().layoutXfbBuffer = currentBlockQualifier.layoutXfbBuffer;
                 oldType.getQualifier().layoutXfbBuffer = currentBlockQualifier.layoutXfbBuffer;
             }
-            if (oldType.isImplicitlySizedArray() && newType.isExplicitlySizedArray())
+            if (oldType.isUnsizedArray() && newType.isSizedArray())
                 oldType.changeOuterArraySize(newType.getOuterArraySize());
 
             //  check and process the member's type, which will include managing xfb information
@@ -3652,11 +3608,11 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT
     if (type.isArray() != (arraySizes != nullptr))
         error(loc, "cannot change arrayness of redeclared block", blockName.c_str(), "");
     else if (type.isArray()) {
-        if (type.isExplicitlySizedArray() && arraySizes->getOuterSize() == UnsizedArraySize)
-            error(loc, "block already declared with size, can't redeclare as implicitly-sized", blockName.c_str(), "");
-        else if (type.isExplicitlySizedArray() && *type.getArraySizes() != *arraySizes)
+        if (type.isSizedArray() && !arraySizes->isSized())
+            error(loc, "block already declared with size, can't redeclare as unsized", blockName.c_str(), "");
+        else if (type.isSizedArray() && *type.getArraySizes() != *arraySizes)
             error(loc, "cannot change array size of redeclared block", blockName.c_str(), "");
-        else if (type.isImplicitlySizedArray() && arraySizes->getOuterSize() != UnsizedArraySize)
+        else if (!type.isSizedArray() && arraySizes->isSized())
             type.changeOuterArraySize(arraySizes->getOuterSize());
     }
 
@@ -3676,7 +3632,7 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT
     trackLinkage(*block);
 }
 
-void TParseContext::paramCheckFix(const TSourceLoc& loc, const TStorageQualifier& qualifier, TType& type)
+void TParseContext::paramCheckFixStorage(const TSourceLoc& loc, const TStorageQualifier& qualifier, TType& type)
 {
     switch (qualifier) {
     case EvqConst:
@@ -3723,7 +3679,7 @@ void TParseContext::paramCheckFix(const TSourceLoc& loc, const TQualifier& quali
             warn(loc, "qualifier has no effect on non-output parameters", "precise", "");
     }
 
-    paramCheckFix(loc, qualifier.storage, type);
+    paramCheckFixStorage(loc, qualifier.storage, type);
 }
 
 void TParseContext::nestedBlockCheck(const TSourceLoc& loc)
@@ -4699,11 +4655,12 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
         if (type.getBasicType() == EbtSampler) {
             int lastBinding = qualifier.layoutBinding;
             if (type.isArray()) {
-                if (type.isImplicitlySizedArray()) {
-                    lastBinding += 1;
-                    warn(loc, "assuming array size of one for compile-time checking of binding numbers for implicitly-sized array", "[]", "");
-                } else
+                if (type.isSizedArray())
                     lastBinding += type.getCumulativeArraySize();
+                else {
+                    lastBinding += 1;
+                    warn(loc, "assuming array size of one for compile-time checking of binding numbers for unsized array", "[]", "");
+                }
             }
             if (spvVersion.vulkan == 0 && lastBinding >= resources.maxCombinedTextureImageUnits)
                 error(loc, "sampler binding not less than gl_MaxCombinedTextureImageUnits", "binding", type.isArray() ? "(using array)" : "");
@@ -4963,7 +4920,7 @@ void TParseContext::fixOffset(const TSourceLoc& loc, TSymbol& symbol)
             // Check for overlap
             int numOffsets = 4;
             if (symbol.getType().isArray()) {
-                if (symbol.getType().isExplicitlySizedArray() && ! symbol.getType().getArraySizes()->isInnerImplicit())
+                if (symbol.getType().isSizedArray() && !symbol.getType().getArraySizes()->isInnerUnsized())
                     numOffsets *= symbol.getType().getCumulativeArraySize();
                 else {
                     // "It is a compile-time error to declare an unsized array of atomic_uint."
@@ -5468,8 +5425,7 @@ TIntermNode* TParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyp
     }
 
     // Fix outer arrayness if variable is unsized, getting size from the initializer
-    if (initializer->getType().isExplicitlySizedArray() &&
-        variable->getType().isImplicitlySizedArray())
+    if (initializer->getType().isSizedArray() && variable->getType().isUnsizedArray())
         variable->getWritableType().changeOuterArraySize(initializer->getType().getOuterArraySize());
 
     // Inner arrayness can also get set by an initializer
index 6193d4a..af1a927 100644 (file)
@@ -348,6 +348,7 @@ public:
     void samplerCheck(const TSourceLoc&, const TType&, const TString& identifier, TIntermTyped* initializer);
     void atomicUintCheck(const TSourceLoc&, const TType&, const TString& identifier);
     void transparentOpaqueCheck(const TSourceLoc&, const TType&, const TString& identifier);
+    void memberQualifierCheck(glslang::TPublicType&);
     void globalQualifierFixCheck(const TSourceLoc&, TQualifier&);
     void globalQualifierTypeCheck(const TSourceLoc&, const TQualifier&, const TPublicType&);
     bool structQualifierErrorCheck(const TSourceLoc&, const TPublicType& pType);
@@ -360,7 +361,7 @@ public:
     bool containsFieldWithBasicType(const TType& type ,TBasicType basicType);
     TSymbol* redeclareBuiltinVariable(const TSourceLoc&, const TString&, const TQualifier&, const TShaderQualifiers&);
     void redeclareBuiltinBlock(const TSourceLoc&, TTypeList& typeList, const TString& blockName, const TString* instanceName, TArraySizes* arraySizes);
-    void paramCheckFix(const TSourceLoc&, const TStorageQualifier&, TType& type);
+    void paramCheckFixStorage(const TSourceLoc&, const TStorageQualifier&, TType& type);
     void paramCheckFix(const TSourceLoc&, const TQualifier&, TType& type);
     void nestedBlockCheck(const TSourceLoc&);
     void nestedStructCheck(const TSourceLoc&);
@@ -408,7 +409,6 @@ public:
     void wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode);
     TIntermNode* addSwitch(const TSourceLoc&, TIntermTyped* expression, TIntermAggregate* body);
 
-    void updateImplicitArraySize(const TSourceLoc&, TIntermNode*, int index);
     TAttributeType attributeFromName(const TString& name) const;
     TAttributes* makeAttributes(const TString& identifier) const;
     TAttributes* makeAttributes(const TString& identifier, TIntermNode* node) const;
index 19c5fe4..10660f7 100644 (file)
@@ -968,7 +968,7 @@ parameter_declaration
         $$ = $1;
 
         parseContext.parameterTypeCheck($1.loc, EvqIn, *$1.param.type);
-        parseContext.paramCheckFix($1.loc, EvqTemporary, *$$.param.type);
+        parseContext.paramCheckFixStorage($1.loc, EvqTemporary, *$$.param.type);
         parseContext.precisionQualifierCheck($$.loc, $$.param.type->getBasicType(), $$.param.type->getQualifier());
     }
     //
@@ -988,7 +988,7 @@ parameter_declaration
         $$ = $1;
 
         parseContext.parameterTypeCheck($1.loc, EvqIn, *$1.param.type);
-        parseContext.paramCheckFix($1.loc, EvqTemporary, *$$.param.type);
+        parseContext.paramCheckFixStorage($1.loc, EvqTemporary, *$$.param.type);
         parseContext.precisionQualifierCheck($$.loc, $$.param.type->getBasicType(), $$.param.type->getQualifier());
     }
     ;
@@ -3121,7 +3121,6 @@ struct_declaration
         }
     }
     | type_qualifier type_specifier struct_declarator_list SEMICOLON {
-        parseContext.globalQualifierFixCheck($1.loc, $1.qualifier);
         if ($2.arraySizes) {
             parseContext.profileRequires($2.loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type");
             parseContext.profileRequires($2.loc, EEsProfile, 300, 0, "arrayed type");
@@ -3131,7 +3130,7 @@ struct_declaration
 
         $$ = $3;
 
-        parseContext.checkNoShaderLayouts($1.loc, $1.shaderQualifiers);
+        parseContext.memberQualifierCheck($1);
         parseContext.voidErrorCheck($2.loc, (*$3)[0].type->getFieldName(), $2.basicType);
         parseContext.mergeQualifiers($2.loc, $2.qualifier, $1.qualifier, true);
         parseContext.precisionQualifierCheck($2.loc, $2.basicType, $2.qualifier);
index 5c1d3c3..b3014a6 100644 (file)
@@ -946,15 +946,15 @@ static const yytype_uint16 yyrline[] =
     2901,  2909,  2914,  2919,  2924,  2932,  2937,  2942,  2947,  2955,
     2960,  2965,  2971,  2977,  2983,  2992,  3001,  3007,  3013,  3019,
     3025,  3030,  3046,  3051,  3056,  3064,  3064,  3075,  3075,  3085,
-    3088,  3101,  3123,  3151,  3155,  3161,  3166,  3177,  3180,  3186,
-    3195,  3198,  3204,  3208,  3209,  3215,  3216,  3217,  3218,  3219,
-    3220,  3221,  3225,  3226,  3230,  3226,  3242,  3243,  3247,  3247,
-    3254,  3254,  3268,  3271,  3279,  3287,  3298,  3299,  3303,  3306,
-    3312,  3319,  3323,  3331,  3335,  3348,  3351,  3357,  3357,  3377,
-    3380,  3386,  3398,  3410,  3413,  3419,  3419,  3434,  3434,  3450,
-    3450,  3471,  3474,  3480,  3483,  3489,  3493,  3500,  3505,  3510,
-    3517,  3520,  3529,  3533,  3542,  3545,  3548,  3556,  3556,  3578,
-    3584,  3587,  3592,  3595
+    3088,  3101,  3123,  3150,  3154,  3160,  3165,  3176,  3179,  3185,
+    3194,  3197,  3203,  3207,  3208,  3214,  3215,  3216,  3217,  3218,
+    3219,  3220,  3224,  3225,  3229,  3225,  3241,  3242,  3246,  3246,
+    3253,  3253,  3267,  3270,  3278,  3286,  3297,  3298,  3302,  3305,
+    3311,  3318,  3322,  3330,  3334,  3347,  3350,  3356,  3356,  3376,
+    3379,  3385,  3397,  3409,  3412,  3418,  3418,  3433,  3433,  3449,
+    3449,  3470,  3473,  3479,  3482,  3488,  3492,  3499,  3504,  3509,
+    3516,  3519,  3528,  3532,  3541,  3544,  3547,  3555,  3555,  3577,
+    3583,  3586,  3591,  3594
 };
 #endif
 
@@ -5101,7 +5101,7 @@ yyreduce:
         (yyval.interm) = (yyvsp[0].interm);
 
         parseContext.parameterTypeCheck((yyvsp[0].interm).loc, EvqIn, *(yyvsp[0].interm).param.type);
-        parseContext.paramCheckFix((yyvsp[0].interm).loc, EvqTemporary, *(yyval.interm).param.type);
+        parseContext.paramCheckFixStorage((yyvsp[0].interm).loc, EvqTemporary, *(yyval.interm).param.type);
         parseContext.precisionQualifierCheck((yyval.interm).loc, (yyval.interm).param.type->getBasicType(), (yyval.interm).param.type->getQualifier());
     }
 #line 5108 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
@@ -5128,7 +5128,7 @@ yyreduce:
         (yyval.interm) = (yyvsp[0].interm);
 
         parseContext.parameterTypeCheck((yyvsp[0].interm).loc, EvqIn, *(yyvsp[0].interm).param.type);
-        parseContext.paramCheckFix((yyvsp[0].interm).loc, EvqTemporary, *(yyval.interm).param.type);
+        parseContext.paramCheckFixStorage((yyvsp[0].interm).loc, EvqTemporary, *(yyval.interm).param.type);
         parseContext.precisionQualifierCheck((yyval.interm).loc, (yyval.interm).param.type->getBasicType(), (yyval.interm).param.type->getQualifier());
     }
 #line 5135 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
@@ -8980,7 +8980,6 @@ yyreduce:
   case 472:
 #line 3123 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
-        parseContext.globalQualifierFixCheck((yyvsp[-3].interm.type).loc, (yyvsp[-3].interm.type).qualifier);
         if ((yyvsp[-2].interm.type).arraySizes) {
             parseContext.profileRequires((yyvsp[-2].interm.type).loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type");
             parseContext.profileRequires((yyvsp[-2].interm.type).loc, EEsProfile, 300, 0, "arrayed type");
@@ -8990,7 +8989,7 @@ yyreduce:
 
         (yyval.interm.typeList) = (yyvsp[-1].interm.typeList);
 
-        parseContext.checkNoShaderLayouts((yyvsp[-3].interm.type).loc, (yyvsp[-3].interm.type).shaderQualifiers);
+        parseContext.memberQualifierCheck((yyvsp[-3].interm.type));
         parseContext.voidErrorCheck((yyvsp[-2].interm.type).loc, (*(yyvsp[-1].interm.typeList))[0].type->getFieldName(), (yyvsp[-2].interm.type).basicType);
         parseContext.mergeQualifiers((yyvsp[-2].interm.type).loc, (yyvsp[-2].interm.type).qualifier, (yyvsp[-3].interm.type).qualifier, true);
         parseContext.precisionQualifierCheck((yyvsp[-2].interm.type).loc, (yyvsp[-2].interm.type).basicType, (yyvsp[-2].interm.type).qualifier);
@@ -9004,38 +9003,38 @@ yyreduce:
             (*(yyval.interm.typeList))[i].type->shallowCopy(type);
         }
     }
-#line 9008 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9007 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 473:
-#line 3151 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3150 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         (yyval.interm.typeList) = new TTypeList;
         (yyval.interm.typeList)->push_back((yyvsp[0].interm.typeLine));
     }
-#line 9017 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9016 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 474:
-#line 3155 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3154 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         (yyval.interm.typeList)->push_back((yyvsp[0].interm.typeLine));
     }
-#line 9025 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9024 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 475:
-#line 3161 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3160 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         (yyval.interm.typeLine).type = new TType(EbtVoid);
         (yyval.interm.typeLine).loc = (yyvsp[0].lex).loc;
         (yyval.interm.typeLine).type->setFieldName(*(yyvsp[0].lex).string);
     }
-#line 9035 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9034 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 476:
-#line 3166 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3165 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         parseContext.arrayOfArrayVersionCheck((yyvsp[-1].lex).loc, (yyvsp[0].interm).arraySizes);
 
@@ -9044,219 +9043,219 @@ yyreduce:
         (yyval.interm.typeLine).type->setFieldName(*(yyvsp[-1].lex).string);
         (yyval.interm.typeLine).type->transferArraySizes((yyvsp[0].interm).arraySizes);
     }
-#line 9048 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9047 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 477:
-#line 3177 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3176 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
     }
-#line 9056 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9055 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 478:
-#line 3180 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3179 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         const char* initFeature = "{ } style initializers";
         parseContext.requireProfile((yyvsp[-2].lex).loc, ~EEsProfile, initFeature);
         parseContext.profileRequires((yyvsp[-2].lex).loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, initFeature);
         (yyval.interm.intermTypedNode) = (yyvsp[-1].interm.intermTypedNode);
     }
-#line 9067 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9066 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 479:
-#line 3186 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3185 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         const char* initFeature = "{ } style initializers";
         parseContext.requireProfile((yyvsp[-3].lex).loc, ~EEsProfile, initFeature);
         parseContext.profileRequires((yyvsp[-3].lex).loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, initFeature);
         (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode);
     }
-#line 9078 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9077 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 480:
-#line 3195 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3194 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         (yyval.interm.intermTypedNode) = parseContext.intermediate.growAggregate(0, (yyvsp[0].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)->getLoc());
     }
-#line 9086 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9085 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 481:
-#line 3198 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3197 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         (yyval.interm.intermTypedNode) = parseContext.intermediate.growAggregate((yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode));
     }
-#line 9094 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9093 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 482:
-#line 3204 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3203 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
-#line 9100 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9099 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 483:
-#line 3208 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3207 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
-#line 9106 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9105 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 484:
-#line 3209 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3208 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
-#line 9112 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9111 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 485:
-#line 3215 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3214 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
-#line 9118 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9117 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 486:
-#line 3216 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3215 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
-#line 9124 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9123 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 487:
-#line 3217 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3216 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
-#line 9130 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9129 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 488:
-#line 3218 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3217 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
-#line 9136 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9135 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 489:
-#line 3219 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3218 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
-#line 9142 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9141 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 490:
-#line 3220 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3219 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
-#line 9148 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9147 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 491:
-#line 3221 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3220 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
-#line 9154 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9153 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 492:
-#line 3225 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3224 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     { (yyval.interm.intermNode) = 0; }
-#line 9160 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9159 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 493:
-#line 3226 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3225 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         parseContext.symbolTable.push();
         ++parseContext.statementNestingLevel;
     }
-#line 9169 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9168 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 494:
-#line 3230 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3229 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]);
         --parseContext.statementNestingLevel;
     }
-#line 9178 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9177 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 495:
-#line 3234 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3233 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         if ((yyvsp[-2].interm.intermNode) && (yyvsp[-2].interm.intermNode)->getAsAggregate())
             (yyvsp[-2].interm.intermNode)->getAsAggregate()->setOperator(EOpSequence);
         (yyval.interm.intermNode) = (yyvsp[-2].interm.intermNode);
     }
-#line 9188 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9187 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 496:
-#line 3242 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3241 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
-#line 9194 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9193 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 497:
-#line 3243 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3242 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
-#line 9200 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9199 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 498:
-#line 3247 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3246 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         ++parseContext.controlFlowNestingLevel;
     }
-#line 9208 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9207 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 499:
-#line 3250 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3249 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         --parseContext.controlFlowNestingLevel;
         (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
     }
-#line 9217 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9216 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 500:
-#line 3254 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3253 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         parseContext.symbolTable.push();
         ++parseContext.statementNestingLevel;
         ++parseContext.controlFlowNestingLevel;
     }
-#line 9227 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9226 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 501:
-#line 3259 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3258 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]);
         --parseContext.statementNestingLevel;
         --parseContext.controlFlowNestingLevel;
         (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
     }
-#line 9238 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9237 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 502:
-#line 3268 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3267 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         (yyval.interm.intermNode) = 0;
     }
-#line 9246 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9245 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 503:
-#line 3271 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3270 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         if ((yyvsp[-1].interm.intermNode) && (yyvsp[-1].interm.intermNode)->getAsAggregate())
             (yyvsp[-1].interm.intermNode)->getAsAggregate()->setOperator(EOpSequence);
         (yyval.interm.intermNode) = (yyvsp[-1].interm.intermNode);
     }
-#line 9256 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9255 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 504:
-#line 3279 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3278 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         (yyval.interm.intermNode) = parseContext.intermediate.makeAggregate((yyvsp[0].interm.intermNode));
         if ((yyvsp[0].interm.intermNode) && (yyvsp[0].interm.intermNode)->getAsBranchNode() && ((yyvsp[0].interm.intermNode)->getAsBranchNode()->getFlowOp() == EOpCase ||
@@ -9265,11 +9264,11 @@ yyreduce:
             (yyval.interm.intermNode) = 0;  // start a fresh subsequence for what's after this case
         }
     }
-#line 9269 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9268 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 505:
-#line 3287 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3286 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         if ((yyvsp[0].interm.intermNode) && (yyvsp[0].interm.intermNode)->getAsBranchNode() && ((yyvsp[0].interm.intermNode)->getAsBranchNode()->getFlowOp() == EOpCase ||
                                             (yyvsp[0].interm.intermNode)->getAsBranchNode()->getFlowOp() == EOpDefault)) {
@@ -9278,76 +9277,76 @@ yyreduce:
         } else
             (yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-1].interm.intermNode), (yyvsp[0].interm.intermNode));
     }
-#line 9282 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9281 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 506:
-#line 3298 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3297 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     { (yyval.interm.intermNode) = 0; }
-#line 9288 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9287 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 507:
-#line 3299 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3298 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     { (yyval.interm.intermNode) = static_cast<TIntermNode*>((yyvsp[-1].interm.intermTypedNode)); }
-#line 9294 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9293 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 508:
-#line 3303 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3302 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
     }
-#line 9302 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9301 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 509:
-#line 3306 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3305 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         parseContext.handleSelectionAttributes(*(yyvsp[-1].interm.attributes), (yyvsp[0].interm.intermNode));
         (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
     }
-#line 9311 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9310 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 510:
-#line 3312 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3311 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         parseContext.boolCheck((yyvsp[-4].lex).loc, (yyvsp[-2].interm.intermTypedNode));
         (yyval.interm.intermNode) = parseContext.intermediate.addSelection((yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.nodePair), (yyvsp[-4].lex).loc);
     }
-#line 9320 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9319 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 511:
-#line 3319 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3318 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         (yyval.interm.nodePair).node1 = (yyvsp[-2].interm.intermNode);
         (yyval.interm.nodePair).node2 = (yyvsp[0].interm.intermNode);
     }
-#line 9329 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9328 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 512:
-#line 3323 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3322 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         (yyval.interm.nodePair).node1 = (yyvsp[0].interm.intermNode);
         (yyval.interm.nodePair).node2 = 0;
     }
-#line 9338 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9337 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 513:
-#line 3331 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3330 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
         parseContext.boolCheck((yyvsp[0].interm.intermTypedNode)->getLoc(), (yyvsp[0].interm.intermTypedNode));
     }
-#line 9347 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9346 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 514:
-#line 3335 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3334 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         parseContext.boolCheck((yyvsp[-2].lex).loc, (yyvsp[-3].interm.type));
 
@@ -9358,28 +9357,28 @@ yyreduce:
         else
             (yyval.interm.intermTypedNode) = 0;
     }
-#line 9362 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9361 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 515:
-#line 3348 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3347 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
     }
-#line 9370 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9369 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 516:
-#line 3351 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3350 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         parseContext.handleSwitchAttributes(*(yyvsp[-1].interm.attributes), (yyvsp[0].interm.intermNode));
         (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
     }
-#line 9379 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9378 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 517:
-#line 3357 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3356 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         // start new switch sequence on the switch stack
         ++parseContext.controlFlowNestingLevel;
@@ -9388,11 +9387,11 @@ yyreduce:
         parseContext.switchLevel.push_back(parseContext.statementNestingLevel);
         parseContext.symbolTable.push();
     }
-#line 9392 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9391 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 518:
-#line 3365 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3364 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         (yyval.interm.intermNode) = parseContext.addSwitch((yyvsp[-7].lex).loc, (yyvsp[-5].interm.intermTypedNode), (yyvsp[-1].interm.intermNode) ? (yyvsp[-1].interm.intermNode)->getAsAggregate() : 0);
         delete parseContext.switchSequenceStack.back();
@@ -9402,27 +9401,27 @@ yyreduce:
         --parseContext.statementNestingLevel;
         --parseContext.controlFlowNestingLevel;
     }
-#line 9406 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9405 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 519:
-#line 3377 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3376 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         (yyval.interm.intermNode) = 0;
     }
-#line 9414 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9413 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 520:
-#line 3380 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3379 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
     }
-#line 9422 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9421 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 521:
-#line 3386 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3385 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         (yyval.interm.intermNode) = 0;
         if (parseContext.switchLevel.size() == 0)
@@ -9435,11 +9434,11 @@ yyreduce:
             (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpCase, (yyvsp[-1].interm.intermTypedNode), (yyvsp[-2].lex).loc);
         }
     }
-#line 9439 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9438 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 522:
-#line 3398 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3397 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         (yyval.interm.intermNode) = 0;
         if (parseContext.switchLevel.size() == 0)
@@ -9449,28 +9448,28 @@ yyreduce:
         else
             (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpDefault, (yyvsp[-1].lex).loc);
     }
-#line 9453 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9452 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 523:
-#line 3410 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3409 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
     }
-#line 9461 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9460 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 524:
-#line 3413 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3412 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         parseContext.handleLoopAttributes(*(yyvsp[-1].interm.attributes), (yyvsp[0].interm.intermNode));
         (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
     }
-#line 9470 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9469 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 525:
-#line 3419 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3418 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         if (! parseContext.limits.whileLoops)
             parseContext.error((yyvsp[-1].lex).loc, "while loops not available", "limitation", "");
@@ -9479,11 +9478,11 @@ yyreduce:
         ++parseContext.statementNestingLevel;
         ++parseContext.controlFlowNestingLevel;
     }
-#line 9483 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9482 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 526:
-#line 3427 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3426 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]);
         (yyval.interm.intermNode) = parseContext.intermediate.addLoop((yyvsp[0].interm.intermNode), (yyvsp[-2].interm.intermTypedNode), 0, true, (yyvsp[-5].lex).loc);
@@ -9491,21 +9490,21 @@ yyreduce:
         --parseContext.statementNestingLevel;
         --parseContext.controlFlowNestingLevel;
     }
-#line 9495 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9494 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 527:
-#line 3434 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3433 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         ++parseContext.loopNestingLevel;
         ++parseContext.statementNestingLevel;
         ++parseContext.controlFlowNestingLevel;
     }
-#line 9505 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9504 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 528:
-#line 3439 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3438 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         if (! parseContext.limits.whileLoops)
             parseContext.error((yyvsp[-7].lex).loc, "do-while loops not available", "limitation", "");
@@ -9517,22 +9516,22 @@ yyreduce:
         --parseContext.statementNestingLevel;
         --parseContext.controlFlowNestingLevel;
     }
-#line 9521 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9520 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 529:
-#line 3450 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3449 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         parseContext.symbolTable.push();
         ++parseContext.loopNestingLevel;
         ++parseContext.statementNestingLevel;
         ++parseContext.controlFlowNestingLevel;
     }
-#line 9532 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9531 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 530:
-#line 3456 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3455 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]);
         (yyval.interm.intermNode) = parseContext.intermediate.makeAggregate((yyvsp[-3].interm.intermNode), (yyvsp[-5].lex).loc);
@@ -9545,81 +9544,81 @@ yyreduce:
         --parseContext.statementNestingLevel;
         --parseContext.controlFlowNestingLevel;
     }
-#line 9549 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9548 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 531:
-#line 3471 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3470 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
     }
-#line 9557 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9556 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 532:
-#line 3474 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3473 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
     }
-#line 9565 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9564 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 533:
-#line 3480 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3479 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
     }
-#line 9573 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9572 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 534:
-#line 3483 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3482 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         (yyval.interm.intermTypedNode) = 0;
     }
-#line 9581 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9580 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 535:
-#line 3489 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3488 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         (yyval.interm.nodePair).node1 = (yyvsp[-1].interm.intermTypedNode);
         (yyval.interm.nodePair).node2 = 0;
     }
-#line 9590 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9589 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 536:
-#line 3493 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3492 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         (yyval.interm.nodePair).node1 = (yyvsp[-2].interm.intermTypedNode);
         (yyval.interm.nodePair).node2 = (yyvsp[0].interm.intermTypedNode);
     }
-#line 9599 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9598 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 537:
-#line 3500 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3499 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         if (parseContext.loopNestingLevel <= 0)
             parseContext.error((yyvsp[-1].lex).loc, "continue statement only allowed in loops", "", "");
         (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpContinue, (yyvsp[-1].lex).loc);
     }
-#line 9609 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9608 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 538:
-#line 3505 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3504 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         if (parseContext.loopNestingLevel + parseContext.switchSequenceStack.size() <= 0)
             parseContext.error((yyvsp[-1].lex).loc, "break statement only allowed in switch and loops", "", "");
         (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpBreak, (yyvsp[-1].lex).loc);
     }
-#line 9619 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9618 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 539:
-#line 3510 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3509 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpReturn, (yyvsp[-1].lex).loc);
         if (parseContext.currentFunctionType->getBasicType() != EbtVoid)
@@ -9627,83 +9626,83 @@ yyreduce:
         if (parseContext.inMain)
             parseContext.postEntryPointReturn = true;
     }
-#line 9631 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9630 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 540:
-#line 3517 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3516 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         (yyval.interm.intermNode) = parseContext.handleReturnValue((yyvsp[-2].lex).loc, (yyvsp[-1].interm.intermTypedNode));
     }
-#line 9639 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9638 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 541:
-#line 3520 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3519 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         parseContext.requireStage((yyvsp[-1].lex).loc, EShLangFragment, "discard");
         (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpKill, (yyvsp[-1].lex).loc);
     }
-#line 9648 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9647 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 542:
-#line 3529 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3528 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
         parseContext.intermediate.setTreeRoot((yyval.interm.intermNode));
     }
-#line 9657 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9656 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 543:
-#line 3533 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3532 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         if ((yyvsp[0].interm.intermNode) != nullptr) {
             (yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-1].interm.intermNode), (yyvsp[0].interm.intermNode));
             parseContext.intermediate.setTreeRoot((yyval.interm.intermNode));
         }
     }
-#line 9668 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9667 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 544:
-#line 3542 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3541 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
     }
-#line 9676 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9675 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 545:
-#line 3545 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3544 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
     }
-#line 9684 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9683 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 546:
-#line 3548 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3547 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         parseContext.requireProfile((yyvsp[0].lex).loc, ~EEsProfile, "extraneous semicolon");
         parseContext.profileRequires((yyvsp[0].lex).loc, ~EEsProfile, 460, nullptr, "extraneous semicolon");
         (yyval.interm.intermNode) = nullptr;
     }
-#line 9694 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9693 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 547:
-#line 3556 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3555 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         (yyvsp[0].interm).function = parseContext.handleFunctionDeclarator((yyvsp[0].interm).loc, *(yyvsp[0].interm).function, false /* not prototype */);
         (yyvsp[0].interm).intermNode = parseContext.handleFunctionDefinition((yyvsp[0].interm).loc, *(yyvsp[0].interm).function);
     }
-#line 9703 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9702 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 548:
-#line 3560 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3559 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         //   May be best done as post process phase on intermediate code
         if (parseContext.currentFunctionType->getBasicType() != EbtVoid && ! parseContext.functionReturnsValue)
@@ -9719,52 +9718,52 @@ yyreduce:
         (yyval.interm.intermNode)->getAsAggregate()->setDebug(parseContext.contextPragma.debug);
         (yyval.interm.intermNode)->getAsAggregate()->setPragmaTable(parseContext.contextPragma.pragmaTable);
     }
-#line 9723 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9722 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 549:
-#line 3578 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3577 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         (yyval.interm.attributes) = (yyvsp[-2].interm.attributes);
         parseContext.requireExtensions((yyvsp[-4].lex).loc, 1, &E_GL_EXT_control_flow_attributes, "attribute");
     }
-#line 9732 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9731 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 550:
-#line 3584 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3583 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         (yyval.interm.attributes) = (yyvsp[0].interm.attributes);
     }
-#line 9740 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9739 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 551:
-#line 3587 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3586 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         (yyval.interm.attributes) = parseContext.mergeAttributes((yyvsp[-2].interm.attributes), (yyvsp[0].interm.attributes));
     }
-#line 9748 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9747 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 552:
-#line 3592 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3591 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         (yyval.interm.attributes) = parseContext.makeAttributes(*(yyvsp[0].lex).string);
     }
-#line 9756 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9755 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
   case 553:
-#line 3595 "MachineIndependent/glslang.y" /* yacc.c:1646  */
+#line 3594 "MachineIndependent/glslang.y" /* yacc.c:1646  */
     {
         (yyval.interm.attributes) = parseContext.makeAttributes(*(yyvsp[-3].lex).string, (yyvsp[-1].interm.intermTypedNode));
     }
-#line 9764 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9763 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
     break;
 
 
-#line 9768 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
+#line 9767 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
       default: break;
     }
   /* User semantic actions sometimes alter yychar, and that requires
@@ -9992,5 +9991,5 @@ yyreturn:
 #endif
   return yyresult;
 }
-#line 3599 "MachineIndependent/glslang.y" /* yacc.c:1906  */
+#line 3598 "MachineIndependent/glslang.y" /* yacc.c:1906  */
 
index aa9c512..5efd7fb 100644 (file)
@@ -268,10 +268,12 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin
 // Recursively merge the implicit array sizes through the objects' respective type trees.
 void TIntermediate::mergeImplicitArraySizes(TType& type, const TType& unitType)
 {
-    if (type.isImplicitlySizedArray() && unitType.isArray()) {
-        int newImplicitArraySize = unitType.isImplicitlySizedArray() ? unitType.getImplicitArraySize() : unitType.getOuterArraySize();
-        if (newImplicitArraySize > type.getImplicitArraySize ())
-            type.setImplicitArraySize(newImplicitArraySize);
+    if (type.isUnsizedArray() && unitType.isArray()) {
+        int newImplicitArraySize = unitType.isSizedArray() ? unitType.getOuterArraySize() : 
+                                                             unitType.getImplicitArraySize();
+        type.updateImplicitArraySize(type.getImplicitArraySize());
+        if (unitType.isArrayVariablyIndexed())
+            type.setArrayVariablyIndexed();
     }
 
     // Type mismatches are caught and reported after this, just be careful for now.
@@ -511,7 +513,9 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
         virtual void visitSymbol(TIntermSymbol* symbol)
         {
             // Implicitly size arrays.
-            symbol->getWritableType().adoptImplicitArraySizes();
+            // If an unsized array is left as unsized, it effectively
+            // becomes run-time sized.
+            symbol->getWritableType().adoptImplicitArraySizes(false);
         }
     } finalLinkTraverser;
 
@@ -766,7 +770,7 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ
 
     int size;
     if (qualifier.isUniformOrBuffer()) {
-        if (type.isExplicitlySizedArray())
+        if (type.isSizedArray())
             size = type.getCumulativeArraySize();
         else
             size = 1;
@@ -914,12 +918,12 @@ int TIntermediate::computeTypeLocationSize(const TType& type, EShLanguage stage)
     // consecutive locations..."
     if (type.isArray()) {
         // TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness
+        // TODO: are there valid cases of having an unsized array with a location?  If so, running this code too early.
         TType elementType(type, 0);
-        if (type.isImplicitlySizedArray()) {
-            // TODO: are there valid cases of having an implicitly-sized array with a location?  If so, running this code too early.
-            return computeTypeLocationSize(elementType, stage);
-        } else
+        if (type.isSizedArray())
             return type.getOuterArraySize() * computeTypeLocationSize(elementType, stage);
+        else
+            return computeTypeLocationSize(elementType, stage);
     }
 
     // "The locations consumed by block and structure members are determined by applying the rules above
@@ -971,11 +975,12 @@ int TIntermediate::computeTypeUniformLocationSize(const TType& type)
     if (type.isArray()) {
         // TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness
         TType elementType(type, 0);
-        if (type.isImplicitlySizedArray()) {
+        if (type.isSizedArray()) {
+            return type.getOuterArraySize() * computeTypeUniformLocationSize(elementType);
+        } else {
             // TODO: are there valid cases of having an implicitly-sized array with a location?  If so, running this code too early.
             return computeTypeUniformLocationSize(elementType);
-        } else
-            return type.getOuterArraySize() * computeTypeUniformLocationSize(elementType);
+        }
     }
 
     // "Each subsequent inner-most member or element gets incremental
@@ -1036,7 +1041,7 @@ unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains
 
     if (type.isArray()) {
         // TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness
-        assert(type.isExplicitlySizedArray());
+        assert(type.isSizedArray());
         TType elementType(type, 0);
         return type.getOuterArraySize() * computeTypeXfbSize(elementType, containsDouble);
     }
index 71e7884..cb05877 100755 (executable)
@@ -2569,8 +2569,8 @@ bool HlslGrammar::acceptParameterDeclaration(TFunction& function)
     TArraySizes* arraySizes = nullptr;
     acceptArraySpecifier(arraySizes);
     if (arraySizes) {
-        if (arraySizes->isImplicit()) {
-            parseContext.error(token.loc, "function parameter array cannot be implicitly sized", "", "");
+        if (arraySizes->hasUnsized()) {
+            parseContext.error(token.loc, "function parameter requires array size", "[]", "");
             return false;
         }
 
index fc3c1bc..1b9cc53 100755 (executable)
@@ -829,6 +829,9 @@ TIntermTyped* HlslParseContext::handleBracketDereference(const TSourceLoc& loc,
     } else {
         // at least one of base and index is variable...
 
+        if (index->getQualifier().isFrontEndConstant())
+            checkIndex(loc, base->getType(), indexValue);
+
         if (base->getType().isScalarOrVec1())
             result = base;
         else if (base->getAsSymbolNode() && wasFlattened(base)) {
@@ -839,14 +842,11 @@ TIntermTyped* HlslParseContext::handleBracketDereference(const TSourceLoc& loc,
             flattened = (result != base);
         } else {
             if (index->getQualifier().isFrontEndConstant()) {
-                if (base->getType().isImplicitlySizedArray())
-                    updateImplicitArraySize(loc, base, indexValue);
-                else
-                    checkIndex(loc, base->getType(), indexValue);
+                if (base->getType().isUnsizedArray())
+                    base->getWritableType().updateImplicitArraySize(indexValue + 1);
                 result = intermediate.addIndex(EOpIndexDirect, base, index, loc);
-            } else {
+            } else
                 result = intermediate.addIndex(EOpIndexIndirect, base, index, loc);
-            }
         }
     }
 
@@ -1318,7 +1318,7 @@ int HlslParseContext::flattenArray(const TVariable& variable, const TType& type,
                                    TFlattenData& flattenData, TString name, bool linkage,
                                    const TQualifier& outerQualifier)
 {
-    assert(type.isArray() && !type.isImplicitlySizedArray());
+    assert(type.isSizedArray());
 
     const int size = type.getOuterArraySize();
     const TType dereferencedType(type, 0);
@@ -3442,16 +3442,16 @@ void HlslParseContext::decomposeStructBufferMethods(const TSourceLoc& loc, TInte
             TIntermAggregate* body = nullptr;
 
             // Length output:
-            if (argArray->getType().isRuntimeSizedArray()) {
-                TIntermTyped* lengthCall = intermediate.addBuiltInFunctionCall(loc, EOpArrayLength, true, argArray,
-                                                                               argNumItems->getType());
-                TIntermTyped* assign = intermediate.addAssign(EOpAssign, argNumItems, lengthCall, loc);
-                body = intermediate.growAggregate(body, assign, loc);
-            } else {
+            if (argArray->getType().isSizedArray()) {
                 const int length = argArray->getType().getOuterArraySize();
                 TIntermTyped* assign = intermediate.addAssign(EOpAssign, argNumItems,
                                                               intermediate.addConstantUnion(length, loc, true), loc);
                 body = intermediate.growAggregate(body, assign, loc);
+            } else {
+                TIntermTyped* lengthCall = intermediate.addBuiltInFunctionCall(loc, EOpArrayLength, true, argArray,
+                                                                               argNumItems->getType());
+                TIntermTyped* assign = intermediate.addAssign(EOpAssign, argNumItems, lengthCall, loc);
+                body = intermediate.growAggregate(body, assign, loc);
             }
 
             // Stride output:
@@ -6295,7 +6295,7 @@ bool HlslParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node
     bool arrayArg = false;
     for (int arg = 0; arg < function.getParamCount(); ++arg) {
         if (function[arg].type->isArray()) {
-            if (! function[arg].type->isExplicitlySizedArray()) {
+            if (function[arg].type->isUnsizedArray()) {
                 // Can't construct from an unsized array.
                 error(loc, "array argument must be sized", "constructor", "");
                 return true;
@@ -6330,11 +6330,10 @@ bool HlslParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node
             return true;
         }
 
-        if (type.isImplicitlySizedArray()) {
+        if (type.isUnsizedArray()) {
             // auto adapt the constructor type to the number of arguments
             type.changeOuterArraySize(function.getParamCount());
-        } else if (type.getOuterArraySize() != function.getParamCount() &&
-                   type.computeNumComponents() > size) {
+        } else if (type.getOuterArraySize() != function.getParamCount() && type.computeNumComponents() > size) {
             error(loc, "array constructor needs one argument per array element", "constructor", "");
             return true;
         }
@@ -6352,7 +6351,7 @@ bool HlslParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node
                 return true;
             }
 
-            if (arraySizes.isInnerImplicit()) {
+            if (arraySizes.isInnerUnsized()) {
                 // "Arrays of arrays ..., and the size for any dimension is optional"
                 // That means we need to adopt (from the first argument) the other array sizes into the type.
                 for (int d = 1; d < arraySizes.getNumDims(); ++d) {
@@ -6607,7 +6606,7 @@ void HlslParseContext::arraySizeCheck(const TSourceLoc& loc, TIntermTyped* expr,
 //
 void HlslParseContext::arraySizeRequiredCheck(const TSourceLoc& loc, const TArraySizes& arraySizes)
 {
-    if (arraySizes.isImplicit())
+    if (arraySizes.hasUnsized())
         error(loc, "array size required", "", "");
 }
 
@@ -6667,7 +6666,7 @@ void HlslParseContext::declareArray(const TSourceLoc& loc, const TString& identi
     // redeclareBuiltinVariable() should have already done the copyUp()
     TType& existingType = symbol->getWritableType();
 
-    if (existingType.isExplicitlySizedArray()) {
+    if (existingType.isSizedArray()) {
         // be more lenient for input arrays to geometry shaders and tessellation control outputs,
         // where the redeclaration is the same size
         return;
@@ -6676,52 +6675,6 @@ void HlslParseContext::declareArray(const TSourceLoc& loc, const TString& identi
     existingType.updateArraySizes(type);
 }
 
-void HlslParseContext::updateImplicitArraySize(const TSourceLoc& loc, TIntermNode *node, int index)
-{
-    // maybe there is nothing to do...
-    TIntermTyped* typedNode = node->getAsTyped();
-    if (typedNode->getType().getImplicitArraySize() > index)
-        return;
-
-    // something to do...
-
-    // Figure out what symbol to lookup, as we will use its type to edit for the size change,
-    // as that type will be shared through shallow copies for future references.
-    TSymbol* symbol = nullptr;
-    int blockIndex = -1;
-    const TString* lookupName = nullptr;
-    if (node->getAsSymbolNode())
-        lookupName = &node->getAsSymbolNode()->getName();
-    else if (node->getAsBinaryNode()) {
-        const TIntermBinary* deref = node->getAsBinaryNode();
-        // This has to be the result of a block dereference, unless it's bad shader code
-        // If it's a uniform block, then an error will be issued elsewhere, but
-        // return early now to avoid crashing later in this function.
-        if (! deref->getLeft()->getAsSymbolNode() || deref->getLeft()->getBasicType() != EbtBlock ||
-            deref->getLeft()->getType().getQualifier().storage == EvqUniform ||
-            deref->getRight()->getAsConstantUnion() == nullptr)
-            return;
-
-        blockIndex = deref->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst();
-
-        lookupName = &deref->getLeft()->getAsSymbolNode()->getName();
-        if (IsAnonymous(*lookupName))
-            lookupName = &(*deref->getLeft()->getType().getStruct())[blockIndex].type->getFieldName();
-    }
-
-    // Lookup the symbol, should only fail if shader code is incorrect
-    symbol = symbolTable.find(*lookupName);
-    if (symbol == nullptr)
-        return;
-
-    if (symbol->getAsFunction()) {
-        error(loc, "array variable name expected", symbol->getName().c_str(), "");
-        return;
-    }
-
-    symbol->getWritableType().setImplicitArraySize(index + 1);
-}
-
 //
 // Enforce non-initializer type/qualifier rules.
 //
@@ -6785,7 +6738,7 @@ TIntermTyped* HlslParseContext::indexStructBufferContent(const TSourceLoc& loc,
 //
 TType* HlslParseContext::getStructBufferContentType(const TType& type) const
 {
-    if (type.getBasicType() != EbtBlock)
+    if (type.getBasicType() != EbtBlock || type.getQualifier().storage != EvqBuffer)
         return nullptr;
 
     const int memberCount = (int)type.getStruct()->size();
@@ -6793,7 +6746,7 @@ TType* HlslParseContext::getStructBufferContentType(const TType& type) const
 
     TType* contentType = (*type.getStruct())[memberCount-1].type;
 
-    return contentType->isRuntimeSizedArray() ? contentType : nullptr;
+    return contentType->isUnsizedArray() ? contentType : nullptr;
 }
 
 //
@@ -7922,8 +7875,7 @@ TIntermNode* HlslParseContext::executeInitializer(const TSourceLoc& loc, TInterm
     }
 
     // Fix outer arrayness if variable is unsized, getting size from the initializer
-    if (initializer->getType().isExplicitlySizedArray() &&
-        variable->getType().isImplicitlySizedArray())
+    if (initializer->getType().isSizedArray() && variable->getType().isUnsizedArray())
         variable->getWritableType().changeOuterArraySize(initializer->getType().getOuterArraySize());
 
     // Inner arrayness can also get set by an initializer
@@ -8025,7 +7977,7 @@ TIntermTyped* HlslParseContext::convertInitializerList(const TSourceLoc& loc, co
         arrayType.copyArraySizes(*type.getArraySizes()); // but get a fresh copy of the array information, to edit below
 
         // edit array sizes to fill in unsized dimensions
-        if (type.isImplicitlySizedArray())
+        if (type.isUnsizedArray())
             arrayType.changeOuterArraySize((int)initList->getSequence().size());
 
         // set unsized array dimensions that can be derived from the initializer's first element
@@ -9621,7 +9573,7 @@ void HlslParseContext::addPatchConstantInvocation()
         const TType& type = *patchConstantFunction[param].type;
         const TBuiltInVariable biType = patchConstantFunction[param].getDeclaredBuiltIn();
 
-        return type.isArray() && !type.isRuntimeSizedArray() && biType == EbvOutputPatch;
+        return type.isSizedArray() && biType == EbvOutputPatch;
     };
     
     // We will perform these steps.  Each is in a scoped block for separation: they could
index 8e2c32e..b16a8c2 100755 (executable)
@@ -164,8 +164,6 @@ public:
     void wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode);
     TIntermNode* addSwitch(const TSourceLoc&, TIntermTyped* expression, TIntermAggregate* body, const TAttributes&);
 
-    void updateImplicitArraySize(const TSourceLoc&, TIntermNode*, int index);
-
     void nestLooping()       { ++loopNestingLevel; }
     void unnestLooping()     { --loopNestingLevel; }
     void nestAnnotations()   { ++annotationNestingLevel; }