Browse Source

Updated glslang.

Бранимир Караџић 5 years ago
parent
commit
2a43c86c24

+ 1 - 1
3rdparty/glslang/SPIRV/GlslangToSpv.cpp

@@ -1448,7 +1448,7 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
         builder.addExecutionMode(shaderEntry, spv::ExecutionModeXfb);
     }
 
-    if (sourceExtensions.find("GL_EXT_ray_flags_primitive_culling") != sourceExtensions.end()) {
+    if (glslangIntermediate->getLayoutPrimitiveCulling()) {
         builder.addCapability(spv::CapabilityRayTraversalPrimitiveCullingProvisionalKHR);
     }
 

+ 4 - 0
3rdparty/glslang/glslang/Include/Types.h

@@ -1235,6 +1235,7 @@ struct TShaderQualifiers {
     bool layoutDerivativeGroupQuads;    // true if layout derivative_group_quadsNV set
     bool layoutDerivativeGroupLinear;   // true if layout derivative_group_linearNV set
     int primitives;                     // mesh shader "max_primitives"DerivativeGroupLinear;   // true if layout derivative_group_linearNV set
+    bool layoutPrimitiveCulling;        // true if layout primitive_culling set
     TLayoutDepth getDepth() const { return layoutDepth; }
 #else
     TLayoutDepth getDepth() const { return EldNone; }
@@ -1268,6 +1269,7 @@ struct TShaderQualifiers {
         layoutOverrideCoverage      = false;
         layoutDerivativeGroupQuads  = false;
         layoutDerivativeGroupLinear = false;
+        layoutPrimitiveCulling      = false;
         primitives                  = TQualifier::layoutNotSet;
         interlockOrdering = EioNone;
 #endif
@@ -1331,6 +1333,8 @@ struct TShaderQualifiers {
             primitives = src.primitives;
         if (src.interlockOrdering != EioNone)
             interlockOrdering = src.interlockOrdering;
+        if (src.layoutPrimitiveCulling)
+            layoutPrimitiveCulling = src.layoutPrimitiveCulling;
 #endif
     }
 };

+ 1 - 1
3rdparty/glslang/glslang/Include/revision.h

@@ -1,3 +1,3 @@
 // This header is generated by the make-revision script.
 
-#define GLSLANG_PATCH_LEVEL 3763
+#define GLSLANG_PATCH_LEVEL 3766

+ 5 - 3
3rdparty/glslang/glslang/MachineIndependent/Intermediate.cpp

@@ -1733,12 +1733,14 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
             case EbtUint64:
             case EbtFloat:
             case EbtDouble:
-                return true;
+                return version >= 400 || extensionRequested(E_GL_ARB_gpu_shader_fp64);
             case EbtInt16:
             case EbtUint16:
-                return extensionRequested(E_GL_AMD_gpu_shader_int16);
+                return (version >= 400 || extensionRequested(E_GL_ARB_gpu_shader_fp64)) &&
+                       extensionRequested(E_GL_AMD_gpu_shader_int16);
             case EbtFloat16:
-                return extensionRequested(E_GL_AMD_gpu_shader_half_float);
+                return (version >= 400 || extensionRequested(E_GL_ARB_gpu_shader_fp64)) &&
+                       extensionRequested(E_GL_AMD_gpu_shader_half_float);
             default:
                 return false;
            }

+ 19 - 1
3rdparty/glslang/glslang/MachineIndependent/ParseHelper.cpp

@@ -5173,6 +5173,12 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
             }
         }
     }
+
+    if (id == "primitive_culling") {
+        requireExtensions(loc, 1, &E_GL_EXT_ray_flags_primitive_culling, "primitive culling");
+        publicType.shaderQualifiers.layoutPrimitiveCulling = true;
+        return;
+    }
 #endif
 
     error(loc, "unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4)", id.c_str(), "");
@@ -6104,6 +6110,8 @@ void TParseContext::checkNoShaderLayouts(const TSourceLoc& loc, const TShaderQua
         error(loc, message, "num_views", "");
     if (shaderQualifiers.interlockOrdering != EioNone)
         error(loc, message, TQualifier::getInterlockOrderingString(shaderQualifiers.interlockOrdering), "");
+    if (shaderQualifiers.layoutPrimitiveCulling)
+        error(loc, "can only be applied as standalone", "primitive_culling", "");
 #endif
 }
 
@@ -8368,6 +8376,16 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con
     {
         checkIoArraysConsistency(loc);
     }
+
+    if (publicType.shaderQualifiers.layoutPrimitiveCulling) {
+        if (publicType.qualifier.storage != EvqTemporary)
+            error(loc, "layout qualifier can not have storage qualifiers", "primitive_culling","", "");
+        else {
+            intermediate.setLayoutPrimitiveCulling();
+        }
+        // Exit early as further checks are not valid
+        return;
+    }
 #endif 
     const TQualifier& qualifier = publicType.qualifier;
 
@@ -8527,7 +8545,7 @@ const TTypeList* TParseContext::recordStructCopy(TStructRecord& record, const TT
     size_t memberCount = tmpType->getStruct()->size();
     size_t originHash = 0, tmpHash = 0;
     std::hash<size_t> hasher;
-    for (uint32_t i = 0; i < memberCount; i++) {
+    for (size_t i = 0; i < memberCount; i++) {
         size_t originMemberHash = hasher(originType->getStruct()->at(i).type->getQualifier().layoutPacking +
                                          originType->getStruct()->at(i).type->getQualifier().layoutMatrix);
         size_t tmpMemberHash = hasher(tmpType->getStruct()->at(i).type->getQualifier().layoutPacking +

+ 17 - 25
3rdparty/glslang/glslang/MachineIndependent/iomapper.cpp

@@ -579,10 +579,7 @@ TDefaultGlslIoResolver::TDefaultGlslIoResolver(const TIntermediate& intermediate
 
 int TDefaultGlslIoResolver::resolveInOutLocation(EShLanguage stage, TVarEntryInfo& ent) {
     const TType& type = ent.symbol->getType();
-    const TString& name = IsAnonymous(ent.symbol->getName()) ?
-                            ent.symbol->getType().getTypeName()
-                            :
-                            ent.symbol->getName();
+    const TString& name = getAccessName(ent.symbol);
     if (currentStage != stage) {
         preStage = currentStage;
         currentStage = stage;
@@ -630,7 +627,7 @@ int TDefaultGlslIoResolver::resolveInOutLocation(EShLanguage stage, TVarEntryInf
         TVarSlotMap::iterator iter = storageSlotMap[resourceKey].find(name);
         if (iter != storageSlotMap[resourceKey].end()) {
             // If interface resource be found, set it has location and this symbol's new location
-            // equal the symbol's explicit location declarated in pre or next stage.
+            // equal the symbol's explicit location declaration in pre or next stage.
             //
             // vs:    out vec4 a;
             // fs:    layout(..., location = 3,...) in vec4 a;
@@ -666,10 +663,7 @@ int TDefaultGlslIoResolver::resolveInOutLocation(EShLanguage stage, TVarEntryInf
 
 int TDefaultGlslIoResolver::resolveUniformLocation(EShLanguage /*stage*/, TVarEntryInfo& ent) {
     const TType& type = ent.symbol->getType();
-    const TString& name = IsAnonymous(ent.symbol->getName()) ?
-                            ent.symbol->getType().getTypeName()
-                            :
-                            ent.symbol->getName();
+    const TString& name = getAccessName(ent.symbol);
     // kick out of not doing this
     if (! doAutoLocationMapping()) {
         return ent.newLocation = -1;
@@ -712,7 +706,7 @@ int TDefaultGlslIoResolver::resolveUniformLocation(EShLanguage /*stage*/, TVarEn
         TVarSlotMap::iterator iter = slotMap.find(name);
         if (iter != slotMap.end()) {
             // If uniform resource be found, set it has location and this symbol's new location
-            // equal the uniform's explicit location declarated in other stage.
+            // equal the uniform's explicit location declaration in other stage.
             //
             // vs:    uniform vec4 a;
             // fs:    layout(..., location = 3,...) uniform vec4 a;
@@ -720,7 +714,7 @@ int TDefaultGlslIoResolver::resolveUniformLocation(EShLanguage /*stage*/, TVarEn
             location = iter->second;
         }
         if (! hasLocation) {
-            // No explicit location declaraten in other stage.
+            // No explicit location declaration in other stage.
             // So we should find a new slot for this uniform.
             //
             // vs:    uniform vec4 a;
@@ -729,7 +723,7 @@ int TDefaultGlslIoResolver::resolveUniformLocation(EShLanguage /*stage*/, TVarEn
             storageSlotMap[resourceKey][name] = location;
         }
     } else {
-        // the first uniform declarated in a program.
+        // the first uniform declaration in a program.
         TVarSlotMap varSlotMap;
         location = getFreeSlot(resourceKey, 0, size);
         varSlotMap[name] = location;
@@ -740,11 +734,8 @@ int TDefaultGlslIoResolver::resolveUniformLocation(EShLanguage /*stage*/, TVarEn
 
 int TDefaultGlslIoResolver::resolveBinding(EShLanguage /*stage*/, TVarEntryInfo& ent) {
     const TType& type = ent.symbol->getType();
-    const TString& name = IsAnonymous(ent.symbol->getName()) ?
-                            ent.symbol->getType().getTypeName()
-                            :
-                            ent.symbol->getName();
-    // On OpenGL arrays of opaque types take a seperate binding for each element
+    const TString& name = getAccessName(ent.symbol);
+    // On OpenGL arrays of opaque types take a separate binding for each element
     int numBindings = intermediate.getSpv().openGl != 0 && type.isSizedArray() ? type.getCumulativeArraySize() : 1;
     TResourceType resource = getResourceType(type);
     // don't need to handle uniform symbol, it will be handled in resolveUniformLocation
@@ -818,10 +809,7 @@ void TDefaultGlslIoResolver::endCollect(EShLanguage /*stage*/) {
 
 void TDefaultGlslIoResolver::reserverStorageSlot(TVarEntryInfo& ent, TInfoSink& infoSink) {
     const TType& type = ent.symbol->getType();
-    const TString& name = IsAnonymous(ent.symbol->getName()) ?
-                            ent.symbol->getType().getTypeName()
-                            :
-                            ent.symbol->getName();
+    const TString& name = getAccessName(ent.symbol);
     TStorageQualifier storage = type.getQualifier().storage;
     EShLanguage stage(EShLangCount);
     switch (storage) {
@@ -881,10 +869,7 @@ void TDefaultGlslIoResolver::reserverStorageSlot(TVarEntryInfo& ent, TInfoSink&
 
 void TDefaultGlslIoResolver::reserverResourceSlot(TVarEntryInfo& ent, TInfoSink& infoSink) {
     const TType& type = ent.symbol->getType();
-    const TString& name = IsAnonymous(ent.symbol->getName()) ?
-                            ent.symbol->getType().getTypeName()
-                            :
-                            ent.symbol->getName();
+    const TString& name = getAccessName(ent.symbol);
     int resource = getResourceType(type);
     if (type.getQualifier().hasBinding()) {
         TVarSlotMap& varSlotMap = resourceSlotMap[resource];
@@ -907,6 +892,13 @@ void TDefaultGlslIoResolver::reserverResourceSlot(TVarEntryInfo& ent, TInfoSink&
     }
 }
 
+const TString& TDefaultGlslIoResolver::getAccessName(const TIntermSymbol* symbol)
+{
+    return symbol->getBasicType() == EbtBlock ?
+        symbol->getType().getTypeName() :
+        symbol->getName();
+}
+
 //TDefaultGlslIoResolver end
 
 /*

+ 1 - 0
3rdparty/glslang/glslang/MachineIndependent/iomapper.h

@@ -203,6 +203,7 @@ public:
     void endCollect(EShLanguage) override;
     void reserverStorageSlot(TVarEntryInfo& ent, TInfoSink& infoSink) override;
     void reserverResourceSlot(TVarEntryInfo& ent, TInfoSink& infoSink) override;
+    const TString& getAccessName(const TIntermSymbol*);
     // in/out symbol and uniform symbol are stored in the same resourceSlotMap, the storage key is used to identify each type of symbol.
     // We use stage and storage qualifier to construct a storage key. it can help us identify the same storage resource used in different stage.
     // if a resource is a program resource and we don't need know it usage stage, we can use same stage to build storage key.

+ 3 - 3
3rdparty/glslang/glslang/MachineIndependent/linkValidate.cpp

@@ -153,7 +153,7 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit)
 
     if (vertices == TQualifier::layoutNotSet)
         vertices = unit.vertices;
-    else if (vertices != unit.vertices) {
+    else if (unit.vertices != TQualifier::layoutNotSet && vertices != unit.vertices) {
         if (language == EShLangGeometry || language == EShLangMeshNV)
             error(infoSink, "Contradictory layout max_vertices values");
         else if (language == EShLangTessControl)
@@ -172,12 +172,12 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit)
 
     if (inputPrimitive == ElgNone)
         inputPrimitive = unit.inputPrimitive;
-    else if (inputPrimitive != unit.inputPrimitive)
+    else if (unit.inputPrimitive != ElgNone && inputPrimitive != unit.inputPrimitive)
         error(infoSink, "Contradictory input layout primitives");
 
     if (outputPrimitive == ElgNone)
         outputPrimitive = unit.outputPrimitive;
-    else if (outputPrimitive != unit.outputPrimitive)
+    else if (unit.outputPrimitive != ElgNone && outputPrimitive != unit.outputPrimitive)
         error(infoSink, "Contradictory output layout primitives");
 
     if (originUpperLeft != unit.originUpperLeft || pixelCenterInteger != unit.pixelCenterInteger)

+ 4 - 0
3rdparty/glslang/glslang/MachineIndependent/localintermediate.h

@@ -265,6 +265,7 @@ public:
         computeDerivativeMode(LayoutDerivativeNone),
         primitives(TQualifier::layoutNotSet),
         numTaskNVBlocks(0),
+        layoutPrimitiveCulling(false),
         autoMapBindings(false),
         autoMapLocations(false),
         flattenUniformArrays(false),
@@ -742,6 +743,8 @@ public:
     void setLayoutDerivativeMode(ComputeDerivativeMode mode) { computeDerivativeMode = mode; }
     bool hasLayoutDerivativeModeNone() const { return computeDerivativeMode != LayoutDerivativeNone; }
     ComputeDerivativeMode getLayoutDerivativeModeNone() const { return computeDerivativeMode; }
+    void setLayoutPrimitiveCulling() { layoutPrimitiveCulling = true; }
+    bool getLayoutPrimitiveCulling() const { return layoutPrimitiveCulling; }
     bool setPrimitives(int m)
     {
         if (primitives != TQualifier::layoutNotSet)
@@ -974,6 +977,7 @@ protected:
     ComputeDerivativeMode computeDerivativeMode;
     int primitives;
     int numTaskNVBlocks;
+    bool layoutPrimitiveCulling;
 
     // Base shift values
     std::array<unsigned int, EResCount> shiftBinding;

+ 2 - 2
3rdparty/glslang/glslang/MachineIndependent/reflection.cpp

@@ -92,8 +92,8 @@ public:
         if (processedDerefs.find(&base) == processedDerefs.end()) {
             processedDerefs.insert(&base);
 
-            uint32_t blockIndex = -1;
-            uint32_t offset     = -1;
+            int blockIndex = -1;
+            int offset     = -1;
             TList<TIntermBinary*> derefs;
             TString baseName = base.getName();
 

+ 1 - 1
3rdparty/glslang/glslang/Public/ShaderLang.h

@@ -68,7 +68,7 @@
 // This should always increase, as some paths to do not consume
 // a more major number.
 // It should increment by one when new functionality is added.
-#define GLSLANG_MINOR_VERSION 13
+#define GLSLANG_MINOR_VERSION 14
 
 //
 // Call before doing any other compiler/linker operations.

+ 69 - 18
3rdparty/glslang/hlsl/hlslParseHelper.cpp

@@ -1169,7 +1169,7 @@ bool HlslParseContext::shouldFlatten(const TType& type, TStorageQualifier qualif
 }
 
 // Top level variable flattening: construct data
-void HlslParseContext::flatten(const TVariable& variable, bool linkage)
+void HlslParseContext::flatten(const TVariable& variable, bool linkage, bool arrayed)
 {
     const TType& type = variable.getType();
 
@@ -1181,8 +1181,15 @@ void HlslParseContext::flatten(const TVariable& variable, bool linkage)
                                                   TFlattenData(type.getQualifier().layoutBinding,
                                                                type.getQualifier().layoutLocation)));
 
-    // the item is a map pair, so first->second is the TFlattenData itself.
-    flatten(variable, type, entry.first->second, variable.getName(), linkage, type.getQualifier(), nullptr);
+    // if flattening arrayed io struct, array each member of dereferenced type
+    if (arrayed) {
+        const TType dereferencedType(type, 0);
+        flatten(variable, dereferencedType, entry.first->second, variable.getName(), linkage,
+                type.getQualifier(), type.getArraySizes());
+    } else {
+        flatten(variable, type, entry.first->second, variable.getName(), linkage,
+                type.getQualifier(), nullptr);
+    }
 }
 
 // Recursively flatten the given variable at the provided type, building the flattenData as we go.
@@ -1256,6 +1263,10 @@ int HlslParseContext::addFlattenedMember(const TVariable& variable, const TType&
             }
         }
 
+        // Only propagate arraysizes here for arrayed io
+        if (variable.getType().getQualifier().isArrayedIo(language) && builtInArraySizes != nullptr)
+            memberVariable->getWritableType().copyArraySizes(*builtInArraySizes);
+
         flattenData.offsets.push_back(static_cast<int>(flattenData.members.size()));
         flattenData.members.push_back(memberVariable);
 
@@ -2068,11 +2079,8 @@ TIntermNode* HlslParseContext::transformEntryPoint(const TSourceLoc& loc, TFunct
     // Further this return/in/out transform by flattening, splitting, and assigning locations
     const auto makeVariableInOut = [&](TVariable& variable) {
         if (variable.getType().isStruct()) {
-            if (variable.getType().getQualifier().isArrayedIo(language)) {
-                if (variable.getType().containsBuiltIn())
-                    split(variable);
-            } else if (shouldFlatten(variable.getType(), EvqVaryingIn /* not assigned yet, but close enough */, true))
-                flatten(variable, false /* don't track linkage here, it will be tracked in assignToInterface() */);
+            bool arrayed = variable.getType().getQualifier().isArrayedIo(language);
+            flatten(variable, false /* don't track linkage here, it will be tracked in assignToInterface() */, arrayed);
         }
         // TODO: flatten arrays too
         // TODO: flatten everything in I/O
@@ -2733,17 +2741,33 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
                wasSplit(binaryNode->getLeft());
     };
 
+    // Return symbol if node is symbol or index ref
+    const auto getSymbol = [](const TIntermTyped* node) -> const TIntermSymbol* {
+        const TIntermSymbol* symbolNode = node->getAsSymbolNode();
+        if (symbolNode != nullptr)
+            return symbolNode;
+
+        const TIntermBinary* binaryNode = node->getAsBinaryNode();
+        if (binaryNode != nullptr && (binaryNode->getOp() == EOpIndexDirect || binaryNode->getOp() == EOpIndexIndirect))
+            return binaryNode->getLeft()->getAsSymbolNode();
+
+        return nullptr;
+    };
+
     // Return true if this stage assigns clip position with potentially inverted Y
     const auto assignsClipPos = [this](const TIntermTyped* node) -> bool {
         return node->getType().getQualifier().builtIn == EbvPosition &&
                (language == EShLangVertex || language == EShLangGeometry || language == EShLangTessEvaluation);
     };
 
+    const TIntermSymbol* leftSymbol = getSymbol(left);
+    const TIntermSymbol* rightSymbol = getSymbol(right);
+
     const bool isSplitLeft    = wasSplit(left) || indexesSplit(left);
     const bool isSplitRight   = wasSplit(right) || indexesSplit(right);
 
-    const bool isFlattenLeft  = wasFlattened(left);
-    const bool isFlattenRight = wasFlattened(right);
+    const bool isFlattenLeft  = wasFlattened(leftSymbol);
+    const bool isFlattenRight = wasFlattened(rightSymbol);
 
     // OK to do a single assign if neither side is split or flattened.  Otherwise, 
     // fall through to a member-wise copy.
@@ -2791,10 +2815,10 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
         memberCount = left->getType().getCumulativeArraySize();
 
     if (isFlattenLeft)
-        leftVariables = &flattenMap.find(left->getAsSymbolNode()->getId())->second.members;
+        leftVariables = &flattenMap.find(leftSymbol->getId())->second.members;
 
     if (isFlattenRight) {
-        rightVariables = &flattenMap.find(right->getAsSymbolNode()->getId())->second.members;
+        rightVariables = &flattenMap.find(rightSymbol->getId())->second.members;
     } else {
         // The RHS is not flattened.  There are several cases:
         // 1. 1 item to copy:  Use the RHS directly.
@@ -2828,8 +2852,10 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
     TStorageQualifier leftStorage = left->getType().getQualifier().storage;
     TStorageQualifier rightStorage = right->getType().getQualifier().storage;
 
-    int leftOffset = findSubtreeOffset(*left);
-    int rightOffset = findSubtreeOffset(*right);
+    int leftOffsetStart = findSubtreeOffset(*left);
+    int rightOffsetStart = findSubtreeOffset(*right);
+    int leftOffset = leftOffsetStart;
+    int rightOffset = rightOffsetStart;
 
     const auto getMember = [&](bool isLeft, const TType& type, int member, TIntermTyped* splitNode, int splitMember,
                                bool flattened)
@@ -2869,10 +2895,35 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
                 }
             }
         } else if (flattened && !shouldFlatten(derefType, isLeft ? leftStorage : rightStorage, false)) {
-            if (isLeft)
+            if (isLeft) {
+                // offset will cycle through variables for arrayed io
+                if (leftOffset >= static_cast<int>(leftVariables->size()))
+                    leftOffset = leftOffsetStart;
                 subTree = intermediate.addSymbol(*(*leftVariables)[leftOffset++]);
-            else
+            } else {
+                // offset will cycle through variables for arrayed io
+                if (rightOffset >= static_cast<int>(rightVariables->size()))
+                    rightOffset = rightOffsetStart;
                 subTree = intermediate.addSymbol(*(*rightVariables)[rightOffset++]);
+            }
+
+            // arrayed io
+            if (subTree->getType().isArray()) {
+                if (!arrayElement.empty()) {
+                    const TType derefType(subTree->getType(), arrayElement.front());
+                    subTree = intermediate.addIndex(EOpIndexDirect, subTree,
+                                                    intermediate.addConstantUnion(arrayElement.front(), loc), loc);
+                    subTree->setType(derefType);
+                } else {
+                    // There's an index operation we should transfer to the output builtin.
+                    assert(splitNode->getAsOperator() != nullptr &&
+                           splitNode->getAsOperator()->getOp() == EOpIndexIndirect);
+                    const TType splitDerefType(subTree->getType(), 0);
+                    subTree = intermediate.addIndex(splitNode->getAsOperator()->getOp(), subTree,
+                                                    splitNode->getAsBinaryNode()->getRight(), loc);
+                    subTree->setType(splitDerefType);
+                }
+            }
         } else {
             // Index operator if it's an aggregate, else EOpNull
             const TOperator accessOp = type.isArray()  ? EOpIndexDirect
@@ -9911,8 +9962,8 @@ void HlslParseContext::addPatchConstantInvocation()
         TVariable* pcfOutput = makeInternalVariable("@patchConstantOutput", outType);
         pcfOutput->getWritableType().getQualifier().storage = EvqVaryingOut;
 
-        if (pcfOutput->getType().containsBuiltIn())
-            split(*pcfOutput);
+        if (pcfOutput->getType().isStruct())
+            flatten(*pcfOutput, false);
 
         assignToInterface(*pcfOutput);
 

+ 1 - 1
3rdparty/glslang/hlsl/hlslParseHelper.h

@@ -276,7 +276,7 @@ protected:
 
     void fixBuiltInIoType(TType&);
 
-    void flatten(const TVariable& variable, bool linkage);
+    void flatten(const TVariable& variable, bool linkage, bool arrayed = false);
     int flatten(const TVariable& variable, const TType&, TFlattenData&, TString name, bool linkage,
                 const TQualifier& outerQualifier, const TArraySizes* builtInArraySizes);
     int flattenStruct(const TVariable& variable, const TType&, TFlattenData&, TString name, bool linkage,