Record gl_in array size in a symbol in ParseContext

Instead of referring to the gl_in symbol in the symbol table, create
a gl_in symbol with the right array size once the array size is known.
This makes the type of TIntermSymbol nodes pointing to gl_in
consistent with the variable type.

BUG=angleproject:2267
TEST=angle_unittests

Change-Id: I31673d33526a91f8d069ee8d7d2f181a49665fd0
Reviewed-on: https://chromium-review.googlesource.com/857004
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index 748b523..78ae880 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -235,7 +235,7 @@
       mGeometryShaderMaxVertices(-1),
       mMaxGeometryShaderInvocations(resources.MaxGeometryShaderInvocations),
       mMaxGeometryShaderMaxVertices(resources.MaxGeometryOutputVertices),
-      mGeometryShaderInputArraySize(0u)
+      mGlInVariableWithArraySize(nullptr)
 {
 }
 
@@ -1896,10 +1896,8 @@
     else if ((mGeometryShaderInputPrimitiveType != EptUndefined) &&
              (variableType.getQualifier() == EvqPerVertexIn))
     {
-        ASSERT(mGeometryShaderInputArraySize > 0u);
-
-        node = new TIntermSymbol(variable);
-        node->getTypePointer()->sizeOutermostUnsizedArray(mGeometryShaderInputArraySize);
+        ASSERT(mGlInVariableWithArraySize != nullptr);
+        node = new TIntermSymbol(mGlInVariableWithArraySize);
     }
     else
     {
@@ -2375,8 +2373,9 @@
             // input primitive declaration.
             if (mGeometryShaderInputPrimitiveType != EptUndefined)
             {
-                ASSERT(mGeometryShaderInputArraySize > 0u);
-                type->sizeOutermostUnsizedArray(mGeometryShaderInputArraySize);
+                ASSERT(mGlInVariableWithArraySize != nullptr);
+                type->sizeOutermostUnsizedArray(
+                    mGlInVariableWithArraySize->getType().getOutermostArraySize());
             }
             else
             {
@@ -2846,11 +2845,17 @@
 void TParseContext::setGeometryShaderInputArraySize(unsigned int inputArraySize,
                                                     const TSourceLoc &line)
 {
-    if (mGeometryShaderInputArraySize == 0u)
+    if (mGlInVariableWithArraySize == nullptr)
     {
-        mGeometryShaderInputArraySize = inputArraySize;
+        TSymbol *glPerVertex              = symbolTable.findBuiltIn("gl_PerVertex", 310);
+        TInterfaceBlock *glPerVertexBlock = static_cast<TInterfaceBlock *>(glPerVertex);
+        TType glInType(glPerVertexBlock, EvqPerVertexIn, TLayoutQualifier::Create());
+        glInType.makeArray(inputArraySize);
+        mGlInVariableWithArraySize =
+            new TVariable(&symbolTable, NewPoolTString("gl_in"), glInType, SymbolType::BuiltIn,
+                          TExtension::EXT_geometry_shader);
     }
-    else if (mGeometryShaderInputArraySize != inputArraySize)
+    else if (mGlInVariableWithArraySize->getType().getOutermostArraySize() != inputArraySize)
     {
         error(line,
               "Array size or input primitive declaration doesn't match the size of earlier sized "
diff --git a/src/compiler/translator/ParseContext.h b/src/compiler/translator/ParseContext.h
index 443da5b..1c88a73 100644
--- a/src/compiler/translator/ParseContext.h
+++ b/src/compiler/translator/ParseContext.h
@@ -648,8 +648,9 @@
     int mMaxGeometryShaderInvocations;
     int mMaxGeometryShaderMaxVertices;
 
-    // Track if all input array sizes are same and matches the latter input primitive declaration.
-    unsigned int mGeometryShaderInputArraySize;
+    // Store gl_in variable with its array size once the array size can be determined. The array
+    // size can also be checked against latter input primitive type declaration.
+    const TVariable *mGlInVariableWithArraySize;
 };
 
 int PaParseStrings(size_t count,