Support struct varying for transform feedback

Capturing struct members is vague In ES 3.00. But the ES 3.10
explicitly says that base-level members of struct are feasible for
transform feedback capture. This implementation fills the gap.

TEST=angle_end2end_tests:TrasnformFeedbackTest*
BUG=angleproject:2241
Change-Id: Ibdf3ae6c2b8b28952e2f7fef1363545cbccad389
Reviewed-on: https://chromium-review.googlesource.com/768613
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/common/utilities.cpp b/src/common/utilities.cpp
index b76d1ba..d9c1193 100644
--- a/src/common/utilities.cpp
+++ b/src/common/utilities.cpp
@@ -7,6 +7,7 @@
 // utilities.cpp: Conversion functions and other utility routines.
 
 #include "common/utilities.h"
+#include <GLSLANG/ShaderVars.h>
 #include "common/mathutil.h"
 #include "common/platform.h"
 
@@ -770,6 +771,38 @@
     return name.substr(0, baseNameLength);
 }
 
+const sh::ShaderVariable *FindShaderVarField(const sh::ShaderVariable &var,
+                                             const std::string &fullName)
+{
+    if (var.fields.empty())
+    {
+        return nullptr;
+    }
+    size_t pos = fullName.find_first_of(".");
+    if (pos == std::string::npos)
+    {
+        return nullptr;
+    }
+    std::string topName = fullName.substr(0, pos);
+    if (topName != var.name)
+    {
+        return nullptr;
+    }
+    std::string fieldName = fullName.substr(pos + 1);
+    if (fieldName.empty())
+    {
+        return nullptr;
+    }
+    for (const auto &field : var.fields)
+    {
+        if (field.name == fieldName)
+        {
+            return &field;
+        }
+    }
+    return nullptr;
+}
+
 unsigned int ArraySizeProduct(const std::vector<unsigned int> &arraySizes)
 {
     unsigned int arraySizeProduct = 1u;