Emit "#version 120" if the shader has array as out parameter.
Review URL: https://codereview.appspot.com/6494082

git-svn-id: https://angleproject.googlecode.com/svn/trunk@1273 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/compiler/VersionGLSL.cpp b/src/compiler/VersionGLSL.cpp
index 26cee05..7a82bb4 100644
--- a/src/compiler/VersionGLSL.cpp
+++ b/src/compiler/VersionGLSL.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
@@ -9,17 +9,22 @@
 static const int GLSL_VERSION_110 = 110;
 static const int GLSL_VERSION_120 = 120;
 
-// We need to scan for three things:
+// We need to scan for the following:
 // 1. "invariant" keyword: This can occur in both - vertex and fragment shaders
 //    but only at the global scope.
 // 2. "gl_PointCoord" built-in variable: This can only occur in fragment shader
 //    but inside any scope.
 // 3. Call to a matrix constructor with another matrix as argument.
 //    (These constructors were reserved in GLSL version 1.10.)
-//
-// If it weren't for (3) then we would only need to scan the global
-// scope of the vertex shader. However, we need to scan the entire
-// shader in both cases.
+// 4. Arrays as "out" function parameters.
+//    GLSL spec section 6.1.1: "When calling a function, expressions that do
+//    not evaluate to l-values cannot be passed to parameters declared as
+//    out or inout."
+//    GLSL 1.1 section 5.8: "Other binary or unary expressions,
+//    non-dereferenced arrays, function names, swizzles with repeated fields,
+//    and constants cannot be l-values."
+//    GLSL 1.2 relaxed the restriction on arrays, section 5.8: "Variables that
+//    are built-in types, entire structures or arrays... are all l-values."
 //
 // TODO(alokp): The following two cases of invariant decalaration get lost
 // during parsing - they do not get carried over to the intermediate tree.
@@ -79,6 +84,26 @@
         }
         break;
       }
+      case EOpParameters: {
+        const TIntermSequence& params = node->getSequence();
+        for (TIntermSequence::const_iterator iter = params.begin();
+             iter != params.end(); ++iter)
+        {
+            const TIntermTyped* param = (*iter)->getAsTyped();
+            if (param->isArray())
+            {
+                TQualifier qualifier = param->getQualifier();
+                if ((qualifier == EvqOut) || (qualifier ==  EvqInOut))
+                {
+                    updateVersion(GLSL_VERSION_120);
+                    break;
+                }
+            }
+        }
+        // Fully processed. No need to visit children.
+        visitChildren = false;
+        break;
+      }
       case EOpConstructMat2:
       case EOpConstructMat3:
       case EOpConstructMat4: {