Improve handling of declarator lists with empty declarations

The code previously failed to check for correctness of layout qualifiers
in case a declarator followed an empty declaration, like so:

layout(packed) uniform float, a;

Fix this by running all necessary declaration checks also for declarators
which follow an empty declaration.

structQualifierErrorCheck is merged into singleDeclarationErrorCheck.

TEST=angle_unittests, WebGL conformance tests
BUG=angleproject:969

Change-Id: Idcb0673e3bcf64087744ff0d260f51a7546f024a
Reviewed-on: https://chromium-review.googlesource.com/264812
Tested-by: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/compiler/translator/ParseContext.h b/src/compiler/translator/ParseContext.h
index 330685c..6c071b8 100644
--- a/src/compiler/translator/ParseContext.h
+++ b/src/compiler/translator/ParseContext.h
@@ -45,7 +45,10 @@
             shaderVersion(100),
             directiveHandler(ext, diagnostics, shaderVersion, debugShaderPrecisionSupported),
             preprocessor(&diagnostics, &directiveHandler),
-            scanner(NULL) {  }
+            scanner(NULL),
+            mDeferredSingleDeclarationErrorCheck(false)
+    {
+    }
     TIntermediate& intermediate; // to hold and build a parse tree
     TSymbolTable& symbolTable;   // symbol table that goes with the language currently being parsed
     sh::GLenum shaderType;              // vertex or fragment language (future: pack or unpack)
@@ -101,13 +104,12 @@
     bool boolErrorCheck(const TSourceLoc&, const TIntermTyped*);
     bool boolErrorCheck(const TSourceLoc&, const TPublicType&);
     bool samplerErrorCheck(const TSourceLoc& line, const TPublicType& pType, const char* reason);
-    bool structQualifierErrorCheck(const TSourceLoc& line, const TPublicType& pType);
     bool locationDeclaratorListCheck(const TSourceLoc& line, const TPublicType &pType);
     bool parameterSamplerErrorCheck(const TSourceLoc& line, TQualifier qualifier, const TType& type);
     bool nonInitConstErrorCheck(const TSourceLoc &line, const TString &identifier, TPublicType *type);
     bool paramErrorCheck(const TSourceLoc& line, TQualifier qualifier, TQualifier paramQualifier, TType* type);
     bool extensionErrorCheck(const TSourceLoc& line, const TString&);
-    bool singleDeclarationErrorCheck(TPublicType &publicType, const TSourceLoc& identifierLocation, const TString &identifier);
+    bool singleDeclarationErrorCheck(TPublicType &publicType, const TSourceLoc &identifierLocation);
     bool layoutLocationErrorCheck(const TSourceLoc& location, const TLayoutQualifier &layoutQualifier);
     bool functionCallLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *);
 
@@ -126,7 +128,8 @@
 
     TPublicType addFullySpecifiedType(TQualifier qualifier, const TPublicType& typeSpecifier);
     TPublicType addFullySpecifiedType(TQualifier qualifier, TLayoutQualifier layoutQualifier, const TPublicType& typeSpecifier);
-    TIntermAggregate* parseSingleDeclaration(TPublicType &publicType, const TSourceLoc& identifierLocation, const TString &identifier);
+    TIntermAggregate *parseSingleDeclaration(TPublicType &publicType,
+                                             const TSourceLoc &identifierOrTypeLocation, const TString &identifier);
     TIntermAggregate* parseSingleArrayDeclaration(TPublicType &publicType, const TSourceLoc& identifierLocation, const TString &identifier, const TSourceLoc& indexLocation, TIntermTyped *indexExpression);
     TIntermAggregate* parseSingleInitDeclaration(TPublicType &publicType, const TSourceLoc& identifierLocation, const TString &identifier, const TSourceLoc& initLocation, TIntermTyped *initializer);
     TIntermAggregate* parseInvariantDeclaration(const TSourceLoc &invariantLoc, const TSourceLoc &identifierLoc, const TString *identifier, const TSymbol *symbol);
@@ -199,6 +202,9 @@
     // Return true if the checks pass
     bool binaryOpCommonCheck(TOperator op, TIntermTyped *left, TIntermTyped *right,
         const TSourceLoc &loc);
+
+    // Set to true when the last/current declarator list was started with an empty declaration.
+    bool mDeferredSingleDeclarationErrorCheck;
 };
 
 int PaParseStrings(size_t count, const char* const string[], const int length[],