Enforce shader input and output variables with a specified location to be single declarations.

This prevents using in and out qualifiers on multiply declared vertex inputs and fragment outputs.

TRAC #23311

Signed-off-by: Nicolas Capens
Signed-off-by: Shannon Woods
Authored-by: Jamie Madill
diff --git a/src/compiler/ParseHelper.cpp b/src/compiler/ParseHelper.cpp
index 7f61665..4de4509 100644
--- a/src/compiler/ParseHelper.cpp
+++ b/src/compiler/ParseHelper.cpp
@@ -649,6 +649,17 @@
     return false;
 }
 
+bool TParseContext::locationDeclaratorListCheck(int line, const TPublicType &pType)
+{
+    if (pType.layoutQualifier.location != -1)
+    {
+        error(line, "location must only be specified for a single input or output variable", "location");
+        return true;
+    }
+
+    return false;
+}
+
 bool TParseContext::parameterSamplerErrorCheck(int line, TQualifier qualifier, const TType& type)
 {
     if ((qualifier == EvqOut || qualifier == EvqInOut) && 
@@ -1322,6 +1333,9 @@
     if (structQualifierErrorCheck(identifierLocation, publicType))
         recover();
 
+    if (locationDeclaratorListCheck(identifierLocation, publicType))
+        recover();
+
     if (nonInitConstErrorCheck(identifierLocation, identifier, publicType, false))
         recover();
 
@@ -1339,6 +1353,9 @@
     if (structQualifierErrorCheck(identifierLocation, publicType))
         recover();
 
+    if (locationDeclaratorListCheck(identifierLocation, publicType))
+        recover();
+
     if (nonInitConstErrorCheck(identifierLocation, identifier, publicType, true))
         recover();
 
@@ -1378,6 +1395,9 @@
     if (structQualifierErrorCheck(identifierLocation, publicType))
         recover();
 
+    if (locationDeclaratorListCheck(identifierLocation, publicType))
+        recover();
+
     TIntermNode* intermNode;
     if (!executeInitializer(identifierLocation, identifier, publicType, initializer, intermNode))
     {