ES31: Implement gl_in in Geometry Shader

This patch intends to implement geometry shader built-in interface
block instance gl_in defined in GL_OES_geometry_shader.

1. Add the definition of gl_in and its interface block gl_PerVertex
   into the symbol table.
2. Support gl_Position as a member of gl_in.
3. Set the array size of gl_in when a valid input primitive type is
   known.
4. Add check that it should be a compile error to index gl_in or
   call length() on gl_in without a valid input primitive declaration.

This patch also adds unit tests to cover all these new features.

BUG=angleproject:1941
TEST=angle_unittests

Change-Id: I8da20c943b29c9ce904834625b396aab6302e1e1
Reviewed-on: https://chromium-review.googlesource.com/605059
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/Initialize.cpp b/src/compiler/translator/Initialize.cpp
index c362ae2..61acd4f 100644
--- a/src/compiler/translator/Initialize.cpp
+++ b/src/compiler/translator/Initialize.cpp
@@ -908,9 +908,32 @@
         }
 
         case GL_GEOMETRY_SHADER_OES:
-            // TODO(jiawei.shao@intel.com): add Geometry Shader built-in variables.
-            break;
+        {
+            // TODO(jiawei.shao@intel.com): add all Geometry Shader built-in variables.
+            const char *extension = "GL_OES_geometry_shader";
 
+            // Add built-in interface block gl_PerVertex and the built-in array gl_in.
+            // TODO(jiawei.shao@intel.com): implement GL_OES_geometry_point_size.
+            const TString *glPerVertexString = NewPoolTString("gl_PerVertex");
+            symbolTable.insertInterfaceBlockNameExt(ESSL3_1_BUILTINS, extension, glPerVertexString);
+
+            TFieldList *fieldList    = NewPoolTFieldList();
+            TSourceLoc zeroSourceLoc = {0, 0, 0, 0};
+            TField *glPositionField  = new TField(new TType(EbtFloat, EbpHigh, EvqPosition, 4),
+                                                 NewPoolTString("gl_Position"), zeroSourceLoc);
+            fieldList->push_back(glPositionField);
+
+            TInterfaceBlock *glInBlock = new TInterfaceBlock(
+                glPerVertexString, fieldList, NewPoolTString("gl_in"), TLayoutQualifier::create());
+
+            // The array size of gl_in is undefined until we get a valid input primitive
+            // declaration.
+            TType glInType(glInBlock, EvqPerVertexIn, TLayoutQualifier::create(), 0);
+            glInType.setArrayUnsized();
+            symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_in", glInType);
+
+            break;
+        }
         default:
             UNREACHABLE();
     }