Add GLSL/ESSL validator/translator support for GL_EXT_shader_framebuffer_fetch.

BUG=angle:834

Change-Id: I2d4e25909a8e1266b9bb7f1d4421324143157c8a
Reviewed-on: https://chromium-review.googlesource.com/231032
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Tested-by: Erik Dahlström <ed@opera.com>
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index 8d21467..89ab9a5 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -796,9 +796,24 @@
     bool sameScope = false;
     TSymbol* symbol = symbolTable.find(identifier, 0, &builtIn, &sameScope);
     if (symbol == 0 || !sameScope) {
-        if (reservedErrorCheck(line, identifier))
-            return true;
-        
+        bool needsReservedErrorCheck = true;
+
+        // gl_LastFragData may be redeclared with a new precision qualifier
+        if (identifier.compare(0, 15, "gl_LastFragData") == 0) {
+            if (type.arraySize == static_cast<const TVariable*>(symbolTable.findBuiltIn("gl_MaxDrawBuffers", shaderVersion))->getConstPointer()->getIConst()) {
+                if (TSymbol* builtInSymbol = symbolTable.findBuiltIn(identifier, shaderVersion)) {
+                    needsReservedErrorCheck = extensionErrorCheck(line, builtInSymbol->getExtension());
+                }
+            } else {
+                error(line, "redeclaration of array with size != gl_MaxDrawBuffers", identifier.c_str());
+                return true;
+            }
+        }
+
+        if (needsReservedErrorCheck)
+            if (reservedErrorCheck(line, identifier))
+                return true;
+
         variable = new TVariable(&identifier, TType(type));
 
         if (type.arraySize)