Implement equality ops for nested structs.

This fixes the WebGL test glsl_misc_struct_equals as well as
several dEQP tests in functional.shaders.struct.

BUG=391957
BUG=angle:910

Change-Id: I09f3cd3f51bbc3541b64dbcfddfe01884ddba6f5
Reviewed-on: https://chromium-review.googlesource.com/247083
Tested-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Zhenyao Mo <zmo@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/compiler/translator/OutputHLSL.h b/src/compiler/translator/OutputHLSL.h
index dec421c..db13d57 100644
--- a/src/compiler/translator/OutputHLSL.h
+++ b/src/compiler/translator/OutputHLSL.h
@@ -73,6 +73,9 @@
     bool writeSameSymbolInitializer(TInfoSinkBase &out, TIntermSymbol *symbolNode, TIntermTyped *expression);
     void writeDeferredGlobalInitializers(TInfoSinkBase &out);
 
+    // Returns the function name
+    TString addStructEqualityFunction(const TStructure &structure);
+
     TParseContext &mContext;
     const ShShaderOutput mOutputType;
     UnfoldShortCircuit *mUnfoldShortCircuit;
@@ -160,6 +163,17 @@
     // shader input structure, which we set in the D3D main function. Instead, we can initialize
     // these static globals after we initialize our other globals.
     std::vector<std::pair<TIntermSymbol*, TIntermTyped*>> mDeferredGlobalInitializers;
+
+    // A list of structure equality comparison functions. It's important to preserve the order at
+    // which we add the functions, since nested structures call each other recursively.
+    struct StructEqualityFunction
+    {
+        const TStructure *structure;
+        TString functionName;
+        TString functionDefinition;
+    };
+
+    std::vector<StructEqualityFunction> mStructEqualityFunctions;
 };
 
 }