diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp
index 921fddd84d991c70b20965aefc3013e7fa1daac3..38fe21390dd5050279c3d5e292997413fd064672 100644
--- a/StandAlone/StandAlone.cpp
+++ b/StandAlone/StandAlone.cpp
@@ -254,6 +254,7 @@ bool CompileFile(char *fileName, ShHandle compiler, int debugOptions, const TBui
 #ifdef MEASURE_MEMORY
 
         GetProcessMemoryInfo(GetCurrentProcess(), &counters, sizeof(counters));
+        printf("Working set size: %d\n", counters.WorkingSetSize);
     }
 #endif
 
diff --git a/Test/array.frag b/Test/array.frag
new file mode 100644
index 0000000000000000000000000000000000000000..090d353da495bcbb3a944f5d4da5c9a0f2064fed
--- /dev/null
+++ b/Test/array.frag
@@ -0,0 +1,57 @@
+#version 130
+
+float gu[];
+float g4[4];
+float g5[5];
+
+uniform int a;
+
+float[4] foo(float a[5])
+{
+    return float[](a[0], a[1], a[2], a[3]);
+}
+
+void bar(float[5]) {}
+
+void main()
+{
+    {
+        float gu[2];  // okay, new scope
+
+        gu[2] = 4.0;  // ERROR, overflow
+    }
+
+    gu[2] = 4.0; // okay
+
+    gu[3] = 3.0;
+    gu[a] = 5.0; // ERROR
+
+    g4 = foo(g5);
+    g5 = g4;  // ERROR
+    gu = g4;  // ERROR
+
+    foo(gu);  // ERROR
+    bar(g5);
+
+    if (float[4](1.0, 2.0, 3.0, 4.0) == g4)
+        gu[0] = 2.0;
+
+    float u[];
+    u[2] = 3.0; // okay
+    float u[5];
+    u[5] = 5.0; // ERROR
+    foo(u);     // okay
+
+    gl_FragData[1000] = vec4(1.0); // ERROR
+    gl_FragData[-1] = vec4(1.0);   // ERROR
+    gl_FragData[3] = vec4(1.0);
+
+    const int ca[] = int[](3, 2);
+    int sum = ca[0];
+    sum += ca[1];
+    sum += ca[2];  // ERROR
+
+    const int ca3[3] = int[](3, 2);  // ERROR
+    int ica[] = int[](3, 2);
+    int ica3[3] = int[](3, 2);       // ERROR
+}
diff --git a/Test/array100.frag b/Test/array100.frag
new file mode 100644
index 0000000000000000000000000000000000000000..87c125b7d31ab961d7a1f57f267838c25cd3ae98
--- /dev/null
+++ b/Test/array100.frag
@@ -0,0 +1,48 @@
+#version 100
+
+float gu[];
+float g4[4];
+float g5[5];
+
+uniform int a;
+
+float[4] foo(float[5] a)  // ERROR  // ERROR
+{
+    return float[](a[0], a[1], a[2], a[3]);  // ERROR
+}
+
+void bar(float[5]) {}
+
+void main()
+{
+    {
+        float gu[2];  // okay, new scope
+
+        gu[2] = 4.0;  // ERROR, overflow
+    }
+
+    gu[2] = 4.0; // okay
+
+    gu[3] = 3.0;
+    gu[a] = 5.0; // ERROR
+
+    g4 = foo(g5);
+    g5 = g4;  // ERROR
+    gu = g4;  // ERROR
+
+    foo(gu);  // ERROR
+    bar(g5);
+
+    if (float[4](1.0, 2.0, 3.0, 4.0) == g4)  // ERROR
+        gu[0] = 2.0;
+
+    float u[];
+    u[2] = 3.0; // okay
+    float u[5];
+    u[5] = 5.0; // ERROR
+    foo(u);     // okay
+
+    gl_FragData[1000] = vec4(1.0); // ERROR
+    gl_FragData[-1] = vec4(1.0);   // ERROR
+    gl_FragData[3] = vec4(1.0);
+}
diff --git a/Test/testlist b/Test/testlist
index 6e8805858d6801c858725f2e1eec8ddbbaba4d93..afe4f9b52e167b8357bc5d8c9022e59f74724eb3 100644
--- a/Test/testlist
+++ b/Test/testlist
@@ -17,3 +17,5 @@ cppIndent.vert
 cppNest.vert
 cppComplexExpr.vert
 pointCoord.frag
+array.frag
+array100.frag
\ No newline at end of file
diff --git a/glslang/Include/BaseTypes.h b/glslang/Include/BaseTypes.h
index ef3f910171500ef6136f395f454568e25cfea77d..c22277cf6df2ff94f930c0d9c8c0d0da0d684a4d 100644
--- a/glslang/Include/BaseTypes.h
+++ b/glslang/Include/BaseTypes.h
@@ -104,14 +104,12 @@ enum TStorageQualifier {
     EvqLast,
 };
 
-//
-// This is just for debug print out, carried along with the definitions above.
-//
+// These will show up in error messages
 __inline const char* getStorageQualifierString(TStorageQualifier q) 
 {
     switch (q) {
-    case EvqTemporary:      return "Temporary";      break;
-    case EvqGlobal:         return "Global";         break;
+    case EvqTemporary:      return "temporary";      break;
+    case EvqGlobal:         return "global";         break;
     case EvqConst:          return "const";          break;
     case EvqConstReadOnly:  return "const (read only)"; break;
     case EvqAttribute:      return "attribute";      break;
@@ -121,14 +119,14 @@ __inline const char* getStorageQualifierString(TStorageQualifier q)
     case EvqIn:             return "in";             break;
     case EvqOut:            return "out";            break;
     case EvqInOut:          return "inout";          break;
-    case EvqPosition:       return "Position";       break;
-    case EvqPointSize:      return "PointSize";      break;
-    case EvqClipVertex:     return "ClipVertex";     break;
-    case EvqFace:           return "FrontFacing";    break;
-    case EvqFragCoord:      return "FragCoord";      break;
-    case EvqPointCoord:     return "PointCoord";     break;
-    case EvqFragColor:      return "FragColor";      break;
-    case EvqFragDepth:      return "FragDepth";      break;
+    case EvqPosition:       return "gl_Position";    break;
+    case EvqPointSize:      return "gl_PointSize";   break;
+    case EvqClipVertex:     return "gl_ClipVertex";  break;
+    case EvqFace:           return "gl_FrontFacing"; break;
+    case EvqFragCoord:      return "gl_FragCoord";   break;
+    case EvqPointCoord:     return "gl_PointCoord";  break;
+    case EvqFragColor:      return "fragment out";   break;
+    case EvqFragDepth:      return "gl_FragDepth";   break;
     default:                return "unknown qualifier";
     }
 }
diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h
index ab665454b9e19ad911a026c3d9cbd2ba7ec9d8c1..b6eaac9d235ab804c99be76479401dc5171daa98 100644
--- a/glslang/Include/Types.h
+++ b/glslang/Include/Types.h
@@ -56,6 +56,24 @@ inline TTypeList* NewPoolTTypeList()
 	return new(memory) TTypeList;
 }
 
+//
+// TODO: TArraySizes memory: This could be replaced by something smaller.
+// Almost all arrays could be handled by two sizes each fitting
+// in 16 bits, needing a real vector only in the cases where there
+// are more than 3 sizes or a size needing more than 16 bits.
+//
+// The type is a pointer, so that it can be non-allocated and zero
+// for the vast majority of non-array types.  Note that means if it
+// is used, it will be containing at least one size.
+
+typedef TVector<int>* TArraySizes;
+
+inline TArraySizes NewPoolTArraySizes()
+{
+    void* memory = GlobalPoolAllocator.allocate(sizeof(TVector<int>));
+    return new(memory) TVector<int>;
+}
+
 //
 // This is a workaround for a problem with the yacc stack,  It can't have
 // types that it thinks have non-trivial constructors.  It should
@@ -79,9 +97,8 @@ public:
     int vectorSize : 4;
     int matrixCols : 4;
     int matrixRows : 4;
-    bool array;
-    int arraySize;
-    TType* userDef;
+    TArraySizes arraySizes;
+    const TType* userDef;
     int line;
 
     void initType(int ln = 0)
@@ -90,8 +107,7 @@ public:
         vectorSize = 1;
         matrixRows = 0;
         matrixCols = 0;
-        array = false;
-        arraySize = 0;
+        arraySizes = 0;
         userDef = 0;
         line = ln;
     }
@@ -110,6 +126,8 @@ public:
 
     void setVector(int s)
     {
+        matrixRows = 0;
+        matrixCols = 0;
         vectorSize = s;
     }
 
@@ -119,12 +137,6 @@ public:
         matrixCols = c;
         vectorSize = 0;
     }
-
-    void setArray(bool a, int s = 0)
-    {
-        array = a;
-        arraySize = s;
-    }
 };
 
 typedef std::map<TTypeList*, TTypeList*> TStructureMap;
@@ -136,7 +148,7 @@ class TType {
 public:
     POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
     explicit TType(TBasicType t, TStorageQualifier q = EvqTemporary, int vs = 1, int mc = 0, int mr = 0) :
-                            type(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), array(false), arraySize(0),
+                            type(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), arraySizes(0),
                             structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0),
                             fieldName(0), mangled(0), typeName(0) 
                             {
@@ -144,7 +156,7 @@ public:
                                 qualifier.precision = EpqNone;
                             }
     explicit TType(const TPublicType &p) :
-                            type(p.type), vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), array(p.array), arraySize(p.arraySize),
+                            type(p.type), vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), arraySizes(p.arraySizes),
                             structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0), typeName(0)
                             {
                                 qualifier = p.qualifier;
@@ -154,7 +166,7 @@ public:
                                 }
                             }
     explicit TType(TTypeList* userDef, const TString& n) :
-                            type(EbtStruct), vectorSize(1), matrixCols(0), matrixRows(0), array(false), arraySize(0),
+                            type(EbtStruct), vectorSize(1), matrixCols(0), matrixRows(0), arraySizes(0),
                             structure(userDef), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0) 
                             {
                                 qualifier.storage = EvqTemporary;
@@ -173,9 +185,13 @@ public:
 		vectorSize = copyOf.vectorSize;
 		matrixCols = copyOf.matrixCols;
 		matrixRows = copyOf.matrixRows;
-		array = copyOf.array;
-		arraySize = copyOf.arraySize;
-		
+
+        if (copyOf.arraySizes) {
+            arraySizes = NewPoolTArraySizes();
+            *arraySizes = *copyOf.arraySizes;
+        } else
+            arraySizes = 0;
+
 		TStructureMapIterator iter;
 		if (copyOf.structure) {
 	        if ((iter = remapper.find(structure)) == remapper.end()) {
@@ -220,9 +236,8 @@ public:
 
     virtual void dereference()
     {
-        if (array) {
-            array = false;
-            arraySize = 0;
+        if (arraySizes) {
+            arraySizes = 0;
             maxArraySize = 0;
         } else if (matrixCols > 0) {
             vectorSize = matrixRows;
@@ -232,7 +247,7 @@ public:
             vectorSize = 1;
     }
 
-    virtual void setElementType(TBasicType t, int s, int mc, int mr, TType* userDef)
+    virtual void setElementType(TBasicType t, int s, int mc, int mr, const TType* userDef)
     { 
         type = t;
         vectorSize = s;
@@ -265,9 +280,15 @@ public:
     virtual int getMatrixRows() const { return matrixRows; }
 
 	virtual bool isMatrix() const { return matrixCols ? true : false; }
-    virtual bool isArray() const  { return array ? true : false; }
-    int getArraySize() const { return arraySize; }
-    void setArraySize(int s) { array = true; arraySize = s; }
+    virtual bool isArray() const  { return arraySizes != 0; }
+    int getArraySize() const { return arraySizes->front(); }
+    void setArraySizes(TArraySizes s) {
+        // copy; we don't want distinct types sharing the same descriptor
+        if (! arraySizes)
+            arraySizes = NewPoolTArraySizes();
+        *arraySizes = *s;
+    }
+    void changeArraySize(int s) { arraySizes->front() = s; }
     void setMaxArraySize (int s) { maxArraySize = s; }
     int getMaxArraySize () const { return maxArraySize; }
     void setArrayInformationType(TType* t) { arrayInformationType = t; }
@@ -336,7 +357,7 @@ public:
                vectorSize == right.vectorSize &&
                matrixCols == right.matrixCols &&
                matrixRows == right.matrixRows &&
-                    array == right.array      && (!array || arraySize == right.arraySize) &&
+              (arraySizes == 0 && right.arraySizes == 0 || (arraySizes && right.arraySizes && *arraySizes == *right.arraySizes)) &&
                 structure == right.structure;
         // don't check the qualifier, it's not ever what's being sought after
     }
@@ -353,10 +374,9 @@ protected:
     int vectorSize       : 4;
     int matrixCols       : 4;
     int matrixRows       : 4;
-	unsigned int array   : 1;
     TQualifier qualifier;
 
-    int arraySize;
+    TArraySizes arraySizes;
 
     TTypeList* structure;      // 0 unless this is a struct
     mutable int structureSize;
diff --git a/glslang/MachineIndependent/Initialize.cpp b/glslang/MachineIndependent/Initialize.cpp
index a02f0a30c1e73f7b180420d1968b1d2516bcabc5..ad428a7420d70e1916e77150547214cbee6b1545 100644
--- a/glslang/MachineIndependent/Initialize.cpp
+++ b/glslang/MachineIndependent/Initialize.cpp
@@ -713,7 +713,7 @@ void TBuiltIns::initialize()
 void TBuiltIns::initialize(const TBuiltInResource &resources)
 {
     //
-    // Initialize all the built-in strings for parsing.
+    // Initialize the context-dependent (resource-dependent) built-in strings for parsing.
     //
     TString StandardUniforms;    
 
@@ -939,7 +939,9 @@ void IdentifyBuiltIns(EShLanguage language, TSymbolTable& symbolTable, const TBu
     case EShLangFragment: {
             // Set up gl_FragData.  The array size.
             TType fragData(EbtFloat, EvqFragColor, 4);
-            fragData.setArraySize(resources.maxDrawBuffers);
+            TArraySizes arraySizes = NewPoolTArraySizes();
+            arraySizes->push_back(resources.maxDrawBuffers);
+            fragData.setArraySizes(arraySizes);
             symbolTable.insert(*new TVariable(NewPoolTString("gl_FragData"),    fragData));
         }
         break;
diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp
index 189d197268acf13ed60ef76065a492514b257ad9..8c1ced7e04f5d65c93b6c123a157cf0f11214526 100644
--- a/glslang/MachineIndependent/ParseHelper.cpp
+++ b/glslang/MachineIndependent/ParseHelper.cpp
@@ -571,9 +571,14 @@ bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction
     if (constType)
         type->getQualifier().storage = EvqConst;
 
-    if (type->isArray() && type->getArraySize() != function.getParamCount()) {
-        error(line, "array constructor needs one argument per array element", "constructor", "");
-        return true;
+    if (type->isArray()) {
+        if (type->getArraySize() == 0) {
+            // auto adapt the constructor type to the number of arguments
+            type->changeArraySize(function.getParamCount());
+        } else if (type->getArraySize() != function.getParamCount()) {
+            error(line, "array constructor needs one argument per array element", "constructor", "");
+            return true;
+        }
     }
 
     if (arrayArg && op != EOpConstructStruct) {
@@ -653,7 +658,7 @@ bool TParseContext::boolErrorCheck(int line, const TIntermTyped* type)
 //
 bool TParseContext::boolErrorCheck(int line, const TPublicType& pType)
 {
-    if (pType.type != EbtBool || pType.array || pType.matrixCols > 1 || (pType.vectorSize > 1)) {
+    if (pType.type != EbtBool || pType.arraySizes || pType.matrixCols > 1 || (pType.vectorSize > 1)) {
         error(line, "boolean expression expected", "", "");
         return true;
     } 
@@ -743,7 +748,7 @@ bool TParseContext::parameterSamplerErrorCheck(int line, TStorageQualifier quali
     return false;
 }
 
-bool TParseContext::containsSampler(TType& type)
+bool TParseContext::containsSampler(const TType& type)
 {
     if (IsSampler(type.getBasicType()))
         return true;
@@ -866,9 +871,6 @@ bool TParseContext::arrayErrorCheck(int line, TString& identifier, TPublicType t
         
         variable = new TVariable(&identifier, TType(type));
 
-        if (type.arraySize)
-            variable->getType().setArraySize(type.arraySize);
-
         if (! symbolTable.insert(*variable)) {
             delete variable;
             error(line, "INTERNAL ERROR inserting new symbol", identifier.c_str(), "");
@@ -897,16 +899,15 @@ bool TParseContext::arrayErrorCheck(int line, TString& identifier, TPublicType t
 
         TType* t = variable->getArrayInformationType();
         while (t != 0) {
-            if (t->getMaxArraySize() > type.arraySize) {
+            if (t->getMaxArraySize() > type.arraySizes->front()) {
                 error(line, "higher index value already used for the array", identifier.c_str(), "");
                 return true;
             }
-            t->setArraySize(type.arraySize);
+            t->setArraySizes(type.arraySizes);
             t = t->getArrayInformationType();
         }
 
-        if (type.arraySize)
-            variable->getType().setArraySize(type.arraySize);
+        variable->getType().setArraySizes(type.arraySizes);
     } 
 
     if (voidErrorCheck(line, identifier, type))
@@ -1094,10 +1095,15 @@ bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPu
         error(line, " cannot initialize this type of qualifier ", variable->getType().getStorageQualifierString(), "");
         return true;
     }
+
+    // Fix arrayness if variable is unsized, getting size for initializer    
+    if (initializer->getType().isArray() && initializer->getType().getArraySize() > 0 && 
+                            type.isArray() &&                   type.getArraySize() == 0)
+        type.changeArraySize(initializer->getType().getArraySize());
+
     //
     // test for and propagate constant
     //
-
     if (qualifier == EvqConst) {
         if (qualifier != initializer->getType().getQualifier().storage) {
             error(line, " assigning non-constant to", "=", "'%s'", variable->getType().getCompleteString().c_str());
@@ -1471,8 +1477,8 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TS
     TType arrayElementType = node->getType();
     arrayElementType.dereference();
 
-    if (index >= node->getType().getArraySize()) {
-        error(line, "", "[", "array index out of range '%d'", index);
+    if (index >= node->getType().getArraySize() || index < 0) {
+        error(line, "", "[", "array index '%d' out of range", index);
         recover();
         index = 0;
     }
diff --git a/glslang/MachineIndependent/ParseHelper.h b/glslang/MachineIndependent/ParseHelper.h
index 6af1c95bfc5553f5cc1085261281f28703ba1073..d3ea23cd17739800d8bc2c96b1bec82e5bca9534 100644
--- a/glslang/MachineIndependent/ParseHelper.h
+++ b/glslang/MachineIndependent/ParseHelper.h
@@ -125,7 +125,7 @@ struct TParseContext {
     bool structQualifierErrorCheck(int line, const TPublicType& pType);
     void setDefaultPrecision(int line, TBasicType, TPrecisionQualifier);
     bool parameterSamplerErrorCheck(int line, TStorageQualifier qualifier, const TType& type);
-    bool containsSampler(TType& type);
+    bool containsSampler(const TType& type);
     bool nonInitConstErrorCheck(int line, TString& identifier, TPublicType& type);
     bool nonInitErrorCheck(int line, TString& identifier, TPublicType& type);
     bool paramErrorCheck(int line, TStorageQualifier qualifier, TType* type);
@@ -154,7 +154,7 @@ int PaParseStrings(char* argv[], int strLen[], int argc, TParseContext&);
 void PaReservedWord();
 int PaIdentOrType(TString& id, TParseContext&, TSymbol*&);
 int PaParseComment(int &lineno, TParseContext&);
-void setInitialState();
+void ResetFlex();
 
 typedef TParseContext* TParseContextPointer;
 extern TParseContextPointer& GetGlobalParseContext();
diff --git a/glslang/MachineIndependent/ShaderLang.cpp b/glslang/MachineIndependent/ShaderLang.cpp
index 4c1d909f59054f6084a9fdecf116b35ee9fbe471..dce9887476bd9b8105e7db8a52cfc2097bdfbc61 100644
--- a/glslang/MachineIndependent/ShaderLang.cpp
+++ b/glslang/MachineIndependent/ShaderLang.cpp
@@ -194,13 +194,11 @@ bool InitializeSymbolTable(TBuiltInStrings* BuiltInStrings, EShLanguage language
 
     GlobalParseContext = &parseContext;
     
-    setInitialState();
-
     assert(symbolTable->isEmpty() || symbolTable->atSharedBuiltInLevel());
        
     //
     // Parse the built-ins.  This should only happen once per
-    // language symbol table.
+    // language symbol table when no 'resources' are passed in.
     //
     // Push the symbol table to give it an initial scope.  This
     // push should not have a corresponding pop, so that built-ins
@@ -208,6 +206,7 @@ bool InitializeSymbolTable(TBuiltInStrings* BuiltInStrings, EShLanguage language
     //
 
     symbolTable->push();
+
     
     //Initialize the Preprocessor
     int ret = InitPreprocessor();
@@ -215,6 +214,8 @@ bool InitializeSymbolTable(TBuiltInStrings* BuiltInStrings, EShLanguage language
         infoSink.info.message(EPrefixInternalError,  "Unable to intialize the Preprocessor");
         return false;
     }
+
+    ResetFlex();
     
     for (TBuiltInStrings::iterator i  = BuiltInStrings[parseContext.language].begin();
                                    i != BuiltInStrings[parseContext.language].end();    ++i) {
@@ -229,15 +230,13 @@ bool InitializeSymbolTable(TBuiltInStrings* BuiltInStrings, EShLanguage language
             return false;
         }
     }
+    FinalizePreprocessor();
 
 	if (resources) {
 		IdentifyBuiltIns(parseContext.language, *symbolTable, *resources);
-	} else {									   
+	} else {
 		IdentifyBuiltIns(parseContext.language, *symbolTable);
 	}
-
-    FinalizePreprocessor();
-
     return true;
 }
 
@@ -279,6 +278,8 @@ int ShCompile(
     TIntermediate intermediate(compiler->infoSink);
     TSymbolTable symbolTable(SymbolTables[compiler->getLanguage()]);
     
+    // Add built-in symbols that are potentially context dependent;
+    // they get popped again further down.
     GenerateBuiltInSymbolTable(resources, compiler->infoSink, &symbolTable, compiler->getLanguage());
 
     TParseContext parseContext(symbolTable, intermediate, compiler->getLanguage(), compiler->infoSink, defaultVersion);
@@ -286,9 +287,9 @@ int ShCompile(
 
     GlobalParseContext = &parseContext;
     
-    setInitialState();
+    ResetFlex();
+    InitPreprocessor();
 
-    InitPreprocessor();    
     //
     // Parse the application's shaders.  All the following symbol table
     // work will be throw-away, so push a new allocation scope that can
diff --git a/glslang/MachineIndependent/SymbolTable.cpp b/glslang/MachineIndependent/SymbolTable.cpp
index 27afc1e5419d25df71c0579edd9881c7e0c79107..15cc52bba4b3673cd29b25725a6f3da0ddce7d92 100644
--- a/glslang/MachineIndependent/SymbolTable.cpp
+++ b/glslang/MachineIndependent/SymbolTable.cpp
@@ -87,10 +87,10 @@ void TType::buildMangledName(TString& mangledName)
         mangledName += static_cast<char>('0' + getMatrixRows());
     }
 
-    if (isArray()) {
+    if (arraySizes) {
 		const int maxSize = 10;
         char buf[maxSize];
-        sprintf_s(buf, maxSize, "%d", arraySize);
+        sprintf_s(buf, maxSize, "%d", arraySizes->front());
         mangledName += '[';
         mangledName += buf;
         mangledName += ']';
diff --git a/glslang/MachineIndependent/glslang.l b/glslang/MachineIndependent/glslang.l
index 52488cbfcc859e19148cc7fe12e40e7eb1fc2f01..49d4f58862634c7a23b6dabb04127083811d4e89 100644
--- a/glslang/MachineIndependent/glslang.l
+++ b/glslang/MachineIndependent/glslang.l
@@ -861,7 +861,7 @@ void updateExtensionBehavior(const char* extName, const char* behavior)
 
 }  // extern "C"
 
-void setInitialState()
+void ResetFlex()
 {
     yy_start = 1;
 }
diff --git a/glslang/MachineIndependent/glslang.y b/glslang/MachineIndependent/glslang.y
index 8be6fbdc924169f44426f03d2cc5758bbe753d9e..dae3e3f3b9d87c9de17802f4caed322d8b3c5756 100644
--- a/glslang/MachineIndependent/glslang.y
+++ b/glslang/MachineIndependent/glslang.y
@@ -101,7 +101,7 @@ Jutta Degener, 1995
             TParameter param;
             TTypeLine typeLine;
             TTypeList* typeList;
-            TVector<int>* intVector;
+            TArraySizes arraySizes;
         };
     } interm;
 }
@@ -321,7 +321,8 @@ postfix_expression
                                 if (parseContext.arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), 0, false, $2.line))
                                     parseContext.recover();
                             }
-                        } else if ( $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst() >= $1->getType().getArraySize()) {
+                        } else if ( $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst() >= $1->getType().getArraySize() ||
+                                    $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst() < 0) {
                             parseContext.error($2.line, "", "[", "array index out of range '%d'", $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst());
                             parseContext.recover();
                         }
@@ -345,8 +346,8 @@ postfix_expression
             TType newType = $1->getType();
             newType.dereference();
             $$->setType(newType);
-            //?? why didn't the code above get the type right?
-            //?? write a deference test
+            //?? why wouldn't the code above get the type right?
+            //?? write a dereference test
         }
     }
     | function_call {
@@ -444,8 +445,7 @@ postfix_expression
                 }
             }
         } else {
-            //?? fix message
-            parseContext.error($2.line, " field selection requires structure, vector, or matrix on left hand side", $3.string->c_str(), "");
+            parseContext.error($2.line, " dot operator requires structure, array, vector, or matrix on left hand side", $3.string->c_str(), "");
             parseContext.recover();
             $$ = $1;
         }
@@ -489,13 +489,16 @@ function_call
         TOperator op = fnCall->getBuiltInOp();
         if (op == EOpArrayLength) {
             // TODO: check for no arguments to .length()
-            if ($1.intermNode->getAsTyped() == 0 || $1.intermNode->getAsTyped()->getType().getArraySize() == 0) {
+            int length;
+            if ($1.intermNode->getAsTyped() == 0 || ! $1.intermNode->getAsTyped()->getType().isArray() || $1.intermNode->getAsTyped()->getType().getArraySize() == 0) {
                 parseContext.error($1.line, "", fnCall->getName().c_str(), "array must be declared with a size before using this method");
                 parseContext.recover();
-            }
+                length = 1;
+            } else
+                length = $1.intermNode->getAsTyped()->getType().getArraySize();
 
             constUnion *unionArray = new constUnion[1];
-            unionArray->setIConst($1.intermNode->getAsTyped()->getType().getArraySize());
+            unionArray->setIConst(length);
             $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $1.line);
         } else if (op != EOpNull) {
             //
@@ -647,8 +650,9 @@ function_identifier
         $$.function = 0;
         $$.intermNode = 0;
 
-        if ($1.array) {
-            parseContext.profileRequires($1.line, ENoProfile, 120, "GL_3DL_array_objects", "array");
+        if ($1.arraySizes) {
+            parseContext.profileRequires($1.line, ENoProfile, 120, "GL_3DL_array_objects", "arrayed constructor");
+            parseContext.profileRequires($1.line, EEsProfile, 300, "GL_3DL_array_objects", "arrayed constructor");
         }
 
         $1.qualifier.precision = EpqNone;
@@ -1284,6 +1288,10 @@ function_header
 parameter_declarator
     // Type + name
     : type_specifier IDENTIFIER {
+        if ($1.arraySizes) {
+            parseContext.profileRequires($1.line, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");
+            parseContext.profileRequires($1.line, EEsProfile, 300, 0, "arrayed type");
+        }
         if ($1.type == EbtVoid) {
             parseContext.error($2.line, "illegal use of type 'void'", $2.string->c_str(), "");
             parseContext.recover();
@@ -1296,13 +1304,18 @@ parameter_declarator
         $$.param = param;
     }
     | type_specifier IDENTIFIER array_specifier {
-        if (parseContext.arraySizeRequiredErrorCheck($3.line, $3.intVector->front()))
+        if ($1.arraySizes) {
+            parseContext.profileRequires($1.line, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");
+            parseContext.profileRequires($1.line, EEsProfile, 300, 0, "arrayed type");
+        }
+
+        if (parseContext.arraySizeRequiredErrorCheck($3.line, $3.arraySizes->front()))
             parseContext.recover();
 
         if (parseContext.reservedErrorCheck($2.line, *$2.string))
             parseContext.recover();
 
-        $1.setArray(true, $3.intVector->front());
+        $1.arraySizes = $3.arraySizes;
 
         TParameter param = { $2.string, new TType($1)};
         $$.line = $2.line;
@@ -1389,7 +1402,7 @@ init_declarator_list
         if (parseContext.arrayQualifierErrorCheck($4.line, $1.type))
             parseContext.recover();
         else {
-            $1.type.setArray(true, $4.intVector->front());
+            $1.type.arraySizes = $4.arraySizes;
             TVariable* variable;
             if (parseContext.arrayErrorCheck($4.line, *$3.string, $1.type, variable))
                 parseContext.recover();
@@ -1405,7 +1418,7 @@ init_declarator_list
         if (parseContext.arrayQualifierErrorCheck($4.line, $1.type))
             parseContext.recover();
         else {
-            $1.type.setArray(true, $4.intVector->front());
+            $1.type.arraySizes = $4.arraySizes;
             if (parseContext.arrayErrorCheck($4.line, *$3.string, $1.type, variable))
                 parseContext.recover();
         }
@@ -1490,7 +1503,7 @@ single_declaration
         if (parseContext.arrayQualifierErrorCheck($3.line, $1))
             parseContext.recover();
         else {
-            $1.setArray(true, $3.intVector->front());
+            $1.arraySizes = $3.arraySizes;
             TVariable* variable;
             if (parseContext.arrayErrorCheck($3.line, *$2.string, $1, variable))
                 parseContext.recover();
@@ -1508,7 +1521,7 @@ single_declaration
         if (parseContext.arrayQualifierErrorCheck($3.line, $1))
             parseContext.recover();
         else {
-            $1.setArray(true, $3.intVector->front());
+            $1.arraySizes = $3.arraySizes;
             if (parseContext.arrayErrorCheck($3.line, *$2.string, $1, variable))
                 parseContext.recover();
         }
@@ -1556,17 +1569,20 @@ fully_specified_type
     : type_specifier {
         $$ = $1;
 
-        if ($1.array) {
-            parseContext.profileRequires($1.line, ENoProfile, 120, "GL_3DL_array_objects", "array");
+        if ($1.arraySizes) {
+            parseContext.profileRequires($1.line, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");
+            parseContext.profileRequires($1.line, EEsProfile, 300, 0, "arrayed type");
         }
     }
     | type_qualifier type_specifier  {
-        if ($2.array)
-            parseContext.profileRequires($1.line, ENoProfile, 120, "GL_3DL_array_objects", "array");
+        if ($2.arraySizes) {
+            parseContext.profileRequires($2.line, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");
+            parseContext.profileRequires($2.line, EEsProfile, 300, 0, "arrayed type");
+        }
 
-        if ($2.array && parseContext.arrayQualifierErrorCheck($2.line, $1)) {
+        if ($2.arraySizes && parseContext.arrayQualifierErrorCheck($2.line, $1)) {
             parseContext.recover();
-            $2.setArray(false);
+            $2.arraySizes = 0;
         }
 
         if ($1.qualifier.storage == EvqAttribute &&
@@ -1833,28 +1849,28 @@ type_specifier
     | type_specifier_nonarray array_specifier {
         $$ = $1;
         $$.qualifier.precision = parseContext.defaultPrecision[$$.type];
-        $$.setArray(true, $2.intVector->front());
+        $$.arraySizes = $2.arraySizes;
     }
     ;
 
 array_specifier
     : LEFT_BRACKET RIGHT_BRACKET {
         $$.line = $1.line;
-        $$.intVector = new TVector<int>;
-        $$.intVector->push_back(0);
+        $$.arraySizes = NewPoolTArraySizes();
+        $$.arraySizes->push_back(0);
     }
     | LEFT_BRACKET constant_expression RIGHT_BRACKET {
         $$.line = $1.line;
-        $$.intVector = new TVector<int>;
+        $$.arraySizes = NewPoolTArraySizes();
 
         int size;
         if (parseContext.arraySizeErrorCheck($2->getLine(), $2, size))
             parseContext.recover();
-        $$.intVector->push_back(size);
+        $$.arraySizes->push_back(size);
     }
     | array_specifier LEFT_BRACKET RIGHT_BRACKET {
         $$ = $1;
-        $$.intVector->push_back(0);
+        $$.arraySizes->push_back(0);
     }
     | array_specifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
         $$ = $1;
@@ -1862,7 +1878,7 @@ array_specifier
         int size;
         if (parseContext.arraySizeErrorCheck($3->getLine(), $3, size))
             parseContext.recover();
-        $$.intVector->push_back(size);
+        $$.arraySizes->push_back(size);
     }
     ;
 
@@ -2443,7 +2459,7 @@ type_specifier_nonarray
         // This is for user defined type names.  The lexical phase looked up the
         // type.
         //
-        TType& structure = static_cast<TVariable*>($1.symbol)->getType();
+        const TType& structure = static_cast<const TVariable*>($1.symbol)->getType();
         $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
         $$.type = EbtStruct;
         $$.userDef = &structure;
@@ -2511,6 +2527,11 @@ struct_declaration_list
 
 struct_declaration
     : type_specifier struct_declarator_list SEMICOLON {
+        if ($1.arraySizes) {
+            parseContext.profileRequires($1.line, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");
+            parseContext.profileRequires($1.line, EEsProfile, 300, 0, "arrayed type");
+        }
+
         $$ = $2;
 
         if (parseContext.voidErrorCheck($1.line, (*$2)[0].type->getFieldName(), $1)) {
@@ -2522,13 +2543,18 @@ struct_declaration
             //
             (*$$)[i].type->setElementType($1.type, $1.vectorSize, $1.matrixCols, $1.matrixRows, $1.userDef);
 
-            if ($1.array)
-                (*$$)[i].type->setArraySize($1.arraySize);
+            if ($1.arraySizes)
+                (*$$)[i].type->setArraySizes($1.arraySizes);
             if ($1.userDef)
                 (*$$)[i].type->setTypeName($1.userDef->getTypeName());
         }
     }
     | type_qualifier type_specifier struct_declarator_list SEMICOLON {
+        if ($2.arraySizes) {
+            parseContext.profileRequires($2.line, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");
+            parseContext.profileRequires($2.line, EEsProfile, 300, 0, "arrayed type");
+        }
+
         $$ = $3;
 
         if (parseContext.voidErrorCheck($2.line, (*$3)[0].type->getFieldName(), $2)) {
@@ -2540,8 +2566,8 @@ struct_declaration
             //
             (*$$)[i].type->setElementType($2.type, $2.vectorSize, $2.matrixCols, $2.matrixRows, $2.userDef);
 
-            if ($2.array)
-                (*$$)[i].type->setArraySize($2.arraySize);
+            if ($2.arraySizes)
+                (*$$)[i].type->setArraySizes($2.arraySizes);
             if ($2.userDef)
                 (*$$)[i].type->setTypeName($2.userDef->getTypeName());
         }
@@ -2568,7 +2594,7 @@ struct_declarator
         $$.type = new TType(EbtVoid);
         $$.line = $1.line;
         $$.type->setFieldName(*$1.string);
-        $$.type->setArraySize($2.intVector->front());
+        $$.type->setArraySizes($2.arraySizes);
     }
     ;
 
diff --git a/glslang/MachineIndependent/intermOut.cpp b/glslang/MachineIndependent/intermOut.cpp
index 16a8d5fab67f85842eb550c4d5cd6e6ffb462856..8520642d6f5cbcfed1ff17af5332124ca247b96f 100644
--- a/glslang/MachineIndependent/intermOut.cpp
+++ b/glslang/MachineIndependent/intermOut.cpp
@@ -64,8 +64,12 @@ TString TType::getCompleteString() const
 
     if (qualifier.storage != EvqTemporary && qualifier.storage != EvqGlobal)
         p += sprintf_s(p, end - p, "%s ", getStorageQualifierString());
-    if (array)
-        p += sprintf_s(p, end - p, "array of ");
+    if (arraySizes) {
+        if (arraySizes->front() == 0)
+            p += sprintf_s(p, end - p, "unsized array of ");
+        else
+            p += sprintf_s(p, end - p, "%d-element array of ", arraySizes->front());
+    }
     if (qualifier.precision != EpqNone)
         p += sprintf_s(p, end - p, "%s ", getPrecisionQualifierString());
     if (matrixCols > 0)