diff --git a/hlsl/hlslParseHelper.cpp b/hlsl/hlslParseHelper.cpp
index 6d2759b0970abfc10b1466d8b865cd0976485dae..272c494b3bdc983a2cf658fdc8060b051125a461 100755
--- a/hlsl/hlslParseHelper.cpp
+++ b/hlsl/hlslParseHelper.cpp
@@ -1174,7 +1174,7 @@ bool HlslParseContext::shouldFlatten(const TType& type) const
 }
 
 // Top level variable flattening: construct data
-void HlslParseContext::flatten(const TSourceLoc& loc, const TVariable& variable)
+void HlslParseContext::flatten(const TVariable& variable)
 {
     const TType& type = variable.getType();
 
@@ -1183,7 +1183,7 @@ void HlslParseContext::flatten(const TSourceLoc& loc, const TVariable& variable)
                                                                type.getQualifier().layoutLocation)));
 
     // the item is a map pair, so first->second is the TFlattenData itself.
-    flatten(loc, variable, type, entry.first->second, "");
+    flatten(variable, type, entry.first->second, "");
 }
 
 // Recursively flatten the given variable at the provided type, building the flattenData as we go.
@@ -1213,15 +1213,15 @@ void HlslParseContext::flatten(const TSourceLoc& loc, const TVariable& variable)
 //
 // so the 4th flattened member in traversal order is ours.
 //
-int HlslParseContext::flatten(const TSourceLoc& loc, const TVariable& variable, const TType& type,
+int HlslParseContext::flatten(const TVariable& variable, const TType& type,
                               TFlattenData& flattenData, TString name)
 {
     // If something is an arrayed struct, the array flattener will recursively call flatten()
     // to then flatten the struct, so this is an "if else": we don't do both.
     if (type.isArray())
-        return flattenArray(loc, variable, type, flattenData, name);
+        return flattenArray(variable, type, flattenData, name);
     else if (type.isStruct())
-        return flattenStruct(loc, variable, type, flattenData, name);
+        return flattenStruct(variable, type, flattenData, name);
     else {
         assert(0); // should never happen
         return -1;
@@ -1230,8 +1230,7 @@ int HlslParseContext::flatten(const TSourceLoc& loc, const TVariable& variable,
 
 // Add a single flattened member to the flattened data being tracked for the composite
 // Returns true for the final flattening level.
-int HlslParseContext::addFlattenedMember(const TSourceLoc& loc,
-                                         const TVariable& variable, const TType& type, TFlattenData& flattenData,
+int HlslParseContext::addFlattenedMember(const TVariable& variable, const TType& type, TFlattenData& flattenData,
                                          const TString& memberName, bool track)
 {
     if (isFinalFlattening(type)) {
@@ -1264,7 +1263,7 @@ int HlslParseContext::addFlattenedMember(const TSourceLoc& loc,
         return static_cast<int>(flattenData.offsets.size())-1; // location of the member reference
     } else {
         // Further recursion required
-        return flatten(loc, variable, type, flattenData, memberName);
+        return flatten(variable, type, flattenData, memberName);
     }
 }
 
@@ -1272,7 +1271,7 @@ int HlslParseContext::addFlattenedMember(const TSourceLoc& loc,
 // equivalent set of individual variables.
 //
 // Assumes shouldFlatten() or equivalent was called first.
-int HlslParseContext::flattenStruct(const TSourceLoc& loc, const TVariable& variable, const TType& type,
+int HlslParseContext::flattenStruct(const TVariable& variable, const TType& type,
                                     TFlattenData& flattenData, TString name)
 {
     assert(type.isStruct());
@@ -1288,7 +1287,7 @@ int HlslParseContext::flattenStruct(const TSourceLoc& loc, const TVariable& vari
         TType& dereferencedType = *members[member].type;
         const TString memberName = name + (name.empty() ? "" : ".") + dereferencedType.getFieldName();
 
-        const int mpos = addFlattenedMember(loc, variable, dereferencedType, flattenData, memberName, false);
+        const int mpos = addFlattenedMember(variable, dereferencedType, flattenData, memberName, false);
         flattenData.offsets[pos++] = mpos;
     }
 
@@ -1299,13 +1298,10 @@ int HlslParseContext::flattenStruct(const TSourceLoc& loc, const TVariable& vari
 // equivalent set of individual variables.
 //
 // Assumes shouldFlatten() or equivalent was called first.
-int HlslParseContext::flattenArray(const TSourceLoc& loc, const TVariable& variable, const TType& type,
+int HlslParseContext::flattenArray(const TVariable& variable, const TType& type,
                                    TFlattenData& flattenData, TString name)
 {
-    assert(type.isArray());
-
-    if (type.isImplicitlySizedArray())
-        error(loc, "cannot flatten implicitly sized array", variable.getName().c_str(), "");
+    assert(type.isArray() && !type.isImplicitlySizedArray());
 
     const int size = type.getOuterArraySize();
     const TType dereferencedType(type, 0);
@@ -1321,7 +1317,7 @@ int HlslParseContext::flattenArray(const TSourceLoc& loc, const TVariable& varia
     for (int element=0; element < size; ++element) {
         char elementNumBuf[20];  // sufficient for MAXINT
         snprintf(elementNumBuf, sizeof(elementNumBuf)-1, "[%d]", element);
-        const int mpos = addFlattenedMember(loc, variable, dereferencedType, flattenData,
+        const int mpos = addFlattenedMember(variable, dereferencedType, flattenData,
                                             name + elementNumBuf, true);
 
         flattenData.offsets[pos++] = mpos;
@@ -1334,7 +1330,7 @@ int HlslParseContext::flattenArray(const TSourceLoc& loc, const TVariable& varia
 bool HlslParseContext::wasFlattened(const TIntermTyped* node) const
 {
     return node != nullptr && node->getAsSymbolNode() != nullptr &&
-        wasFlattened(node->getAsSymbolNode()->getId());
+           wasFlattened(node->getAsSymbolNode()->getId());
 }
 
 // Return true if we have split this structure
@@ -1659,7 +1655,7 @@ TIntermAggregate* HlslParseContext::handleFunctionDefinition(const TSourceLoc& l
             if (shouldFlatten(variable->getType())) {
                 // Expand the AST parameter nodes (but not the name mangling or symbol table view)
                 // for structures that need to be flattened.
-                flatten(loc, *variable);
+                flatten(*variable);
                 const TTypeList* structure = variable->getType().getStruct();
                 for (int mem = 0; mem < (int)structure->size(); ++mem) {
                     paramNodes = intermediate.growAggregate(paramNodes,
@@ -1909,7 +1905,7 @@ TIntermNode* HlslParseContext::transformEntryPoint(const TSourceLoc& loc, TFunct
             // struct inputs to the vertex stage and outputs from the fragment stage must be flattened
             if ((language == EShLangVertex   && qualifier == EvqVaryingIn) ||
                 (language == EShLangFragment && qualifier == EvqVaryingOut))
-                flatten(loc, variable);
+                flatten(variable);
             // Structs contain interstage IO must be split
             else if (variable.getType().containsBuiltInInterstageIO(language))
                 split(variable);
@@ -2457,7 +2453,7 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
 
     // OK to do a single assign if both are split, or both are unsplit.  But if one is and the other
     // isn't, we fall back to a member-wise copy.
-    if (! isFlattenLeft && ! isFlattenRight && !isSplitLeft && !isSplitRight) {
+    if (!isFlattenLeft && !isFlattenRight && !isSplitLeft && !isSplitRight) {
         // Clip and cull distance requires more processing.  See comment above assignClipCullDistance.
         if (isClipOrCullDistance(left->getType())) {
             const int semanticId = left->getType().getQualifier().layoutLocation;
@@ -2529,21 +2525,14 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
 
     const auto getMember = [&](bool isLeft, TIntermTyped* node, int member, TIntermTyped* splitNode, int splitMember)
                            -> TIntermTyped * {
-        TIntermTyped* subTree;
-
-        const bool flattened      = isLeft ? isFlattenLeft : isFlattenRight;
-        const bool split          = isLeft ? isSplitLeft : isSplitRight;
-        const TIntermTyped* outer = isLeft ? outerLeft   : outerRight;
-        const TVector<TVariable*>& flatVariables = isLeft ? *leftVariables : *rightVariables;
-
-        // Index operator if it's an aggregate, else EOpNull
-        const TOperator op = node->getType().isArray()  ? EOpIndexDirect : 
-                             node->getType().isStruct() ? EOpIndexDirectStruct : EOpNull;
+        const bool flattened = isLeft ? isFlattenLeft : isFlattenRight;
+        const bool split     = isLeft ? isSplitLeft   : isSplitRight;
 
+        TIntermTyped* subTree;
         const TType derefType(node->getType(), member);
-
         if (split && derefType.isBuiltInInterstageIO(language)) {
             // copy from interstage IO built-in if needed
+            const TIntermTyped* outer = isLeft ? outerLeft : outerRight;
             subTree = intermediate.addSymbol(*interstageBuiltInIo.find(
                                              HlslParseContext::tInterstageIoData(derefType, outer->getType()))->second);
 
@@ -2556,14 +2545,19 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
                 subTree->setType(splitDerefType);
             }
         } else if (flattened && isFinalFlattening(derefType)) {
+            const TVector<TVariable*>& flatVariables = isLeft ? *leftVariables : *rightVariables;
             subTree = intermediate.addSymbol(*flatVariables[memberIdx++]);
         } else {
-            if (op == EOpNull) {
+            // Index operator if it's an aggregate, else EOpNull
+            const TOperator accessOp = node->getType().isArray()  ? EOpIndexDirect
+                                     : node->getType().isStruct() ? EOpIndexDirectStruct
+                                     : EOpNull;
+            if (accessOp == EOpNull) {
                 subTree = splitNode;
             } else {
+                subTree = intermediate.addIndex(accessOp, splitNode, intermediate.addConstantUnion(splitMember, loc),
+                                                loc);
                 const TType splitDerefType(splitNode->getType(), splitMember);
-
-                subTree = intermediate.addIndex(op, splitNode, intermediate.addConstantUnion(splitMember, loc), loc);
                 subTree->setType(splitDerefType);
             }
         }
@@ -2585,7 +2579,7 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
         // flattened, so have to do member-by-member assignment:
 
         if (left->getType().isArray() || right->getType().isArray()) {
-            const int elementsL = left->getType().isArray() ? left->getType().getOuterArraySize() : 1;
+            const int elementsL = left->getType().isArray()  ? left->getType().getOuterArraySize()  : 1;
             const int elementsR = right->getType().isArray() ? right->getType().getOuterArraySize() : 1;
 
             // The arrays may not be the same size, e.g, if the size has been forced for EbvTessLevelInner or Outer.
@@ -7318,7 +7312,7 @@ TIntermNode* HlslParseContext::declareVariable(const TSourceLoc& loc, const TStr
         return nullptr;
 
     if (flattenVar)
-        flatten(loc, *symbol->getAsVariable());
+        flatten(*symbol->getAsVariable());
 
     if (initializer == nullptr)
         return nullptr;
diff --git a/hlsl/hlslParseHelper.h b/hlsl/hlslParseHelper.h
index 4c20364c0f5ad017319b9081904649f945d196e1..ef814097da2d22d837980eb094363898070febdb 100755
--- a/hlsl/hlslParseHelper.h
+++ b/hlsl/hlslParseHelper.h
@@ -249,7 +249,7 @@ protected:
     bool shouldFlatten(const TType&) const;
     bool wasFlattened(const TIntermTyped* node) const;
     bool wasFlattened(int id) const { return flattenMap.find(id) != flattenMap.end(); }
-    int  addFlattenedMember(const TSourceLoc& loc, const TVariable&, const TType&, TFlattenData&, const TString& name, bool track);
+    int  addFlattenedMember(const TVariable&, const TType&, TFlattenData&, const TString& name, bool track);
     bool isFinalFlattening(const TType& type) const { return !(type.isStruct() || type.isArray()); }
 
     // Structure splitting (splits interstage built-in types into its own struct)
@@ -266,10 +266,10 @@ protected:
 
     void fixBuiltInIoType(TType&);
 
-    void flatten(const TSourceLoc& loc, const TVariable& variable);
-    int flatten(const TSourceLoc& loc, const TVariable& variable, const TType&, TFlattenData&, TString name);
-    int flattenStruct(const TSourceLoc& loc, const TVariable& variable, const TType&, TFlattenData&, TString name);
-    int flattenArray(const TSourceLoc& loc, const TVariable& variable, const TType&, TFlattenData&, TString name);
+    void flatten(const TVariable& variable);
+    int flatten(const TVariable& variable, const TType&, TFlattenData&, TString name);
+    int flattenStruct(const TVariable& variable, const TType&, TFlattenData&, TString name);
+    int flattenArray(const TVariable& variable, const TType&, TFlattenData&, TString name);
 
     bool hasUniform(const TQualifier& qualifier) const;
     void clearUniform(TQualifier& qualifier);