diff --git a/src/libs/glsl/glsl.h b/src/libs/glsl/glsl.h
index 1916fc33f7c4bfa3cd04474fc8dac27b439d38d1..73f35be0c1efe9fad5c514fd0340d183566ecee3 100644
--- a/src/libs/glsl/glsl.h
+++ b/src/libs/glsl/glsl.h
@@ -58,8 +58,10 @@ class UIntType;
 class FloatType;
 class DoubleType;
 class OpaqueType;
+class IndexType;
 class VectorType;
 class MatrixType;
+class ArrayType;
 
 // symbols
 class Symbol;
diff --git a/src/libs/glsl/glslengine.cpp b/src/libs/glsl/glslengine.cpp
index ec5c40a551e750c51910c35aa679ad7e4110576b..6b11bc5f3094a7b84158ad641ff72277a98db347 100644
--- a/src/libs/glsl/glslengine.cpp
+++ b/src/libs/glsl/glslengine.cpp
@@ -155,7 +155,8 @@ const VectorType *Engine::vectorType(const Type *elementType, int dimension)
 
 const MatrixType *Engine::matrixType(const Type *elementType, int columns, int rows)
 {
-    return _matrixTypes.intern(MatrixType(elementType, columns, rows));
+    return _matrixTypes.intern(MatrixType(elementType, columns, rows,
+                                          vectorType(elementType, rows)));
 }
 
 QList<DiagnosticMessage> Engine::diagnosticMessages() const
diff --git a/src/libs/glsl/glsltype.h b/src/libs/glsl/glsltype.h
index a1608b8adec48897c86c33d10f136863ecc5ba23..46ba3913eddcf06e7415c8588d805e9d00ae08c0 100644
--- a/src/libs/glsl/glsltype.h
+++ b/src/libs/glsl/glsltype.h
@@ -46,8 +46,10 @@ public:
     virtual const FloatType *asFloatType() const { return 0; }
     virtual const DoubleType *asDoubleType() const { return 0; }
     virtual const OpaqueType *asOpaqueType() const { return 0; }
+    virtual const IndexType *asIndexType() const { return 0; }
     virtual const VectorType *asVectorType() const { return 0; }
     virtual const MatrixType *asMatrixType() const { return 0; }
+    virtual const ArrayType *asArrayType() const { return 0; }
 
     virtual const Struct *asStructType() const { return 0; }
     virtual const Function *asFunctionType() const { return 0; }
diff --git a/src/libs/glsl/glsltypes.cpp b/src/libs/glsl/glsltypes.cpp
index 8d3e1964b89c7000c9fc9298c81052ba3a827ea6..3e53fa4f8c75da0ab7284509b3dc2daff186fc6b 100644
--- a/src/libs/glsl/glsltypes.cpp
+++ b/src/libs/glsl/glsltypes.cpp
@@ -162,7 +162,7 @@ void VectorType::populateMembers(Engine *engine, const char *components)
     // Single component swizzles.
     for (int x = 0; x < _dimension; ++x) {
         const QString *name = engine->identifier(components + x, 1);
-        add(engine->newVariable(this, *name, _elementType));
+        add(engine->newVariable(this, *name, elementType()));
     }
 
     // Two component swizzles.
@@ -170,7 +170,7 @@ void VectorType::populateMembers(Engine *engine, const char *components)
     if (_dimension == 2)
         vec2Type = this;
     else
-        vec2Type = engine->vectorType(_elementType, 2);
+        vec2Type = engine->vectorType(elementType(), 2);
     for (int x = 0; x < _dimension; ++x) {
         for (int y = 0; y < _dimension; ++y) {
             QString name;
@@ -188,7 +188,7 @@ void VectorType::populateMembers(Engine *engine, const char *components)
     else if (_dimension < 3)
         return;
     else
-        vec3Type = engine->vectorType(_elementType, 3);
+        vec3Type = engine->vectorType(elementType(), 3);
     for (int x = 0; x < _dimension; ++x) {
         for (int y = 0; y < _dimension; ++y) {
             for (int z = 0; z < _dimension; ++z) {
@@ -228,7 +228,7 @@ bool VectorType::isEqualTo(const Type *other) const
         if (const VectorType *v = other->asVectorType()) {
             if (_dimension != v->dimension())
                 return false;
-            else if (_elementType != v->elementType())
+            else if (elementType() != v->elementType())
                 return false;
             return true;
         }
@@ -243,7 +243,7 @@ bool VectorType::isLessThan(const Type *other) const
     Q_ASSERT(vec != 0);
     if (_dimension < vec->dimension())
         return true;
-    else if (_dimension == vec->dimension() && _elementType < vec->elementType())
+    else if (_dimension == vec->dimension() && elementType() < vec->elementType())
         return true;
     return false;
 }
@@ -280,6 +280,23 @@ bool MatrixType::isLessThan(const Type *other) const
     return false;
 }
 
+bool ArrayType::isEqualTo(const Type *other) const
+{
+    if (other) {
+        if (const ArrayType *array = other->asArrayType())
+            return elementType()->isEqualTo(array->elementType());
+    }
+    return false;
+}
+
+bool ArrayType::isLessThan(const Type *other) const
+{
+    Q_ASSERT(other != 0);
+    const ArrayType *array = other->asArrayType();
+    Q_ASSERT(array != 0);
+    return elementType() < array->elementType();
+}
+
 void Struct::add(Symbol *member)
 {
     _members.append(member);
diff --git a/src/libs/glsl/glsltypes.h b/src/libs/glsl/glsltypes.h
index 7a2481ee6a20d9c5f6d401056a61cd66e0b0dbf1..74e969f80fbd722b325723c367b11250f627bf57 100644
--- a/src/libs/glsl/glsltypes.h
+++ b/src/libs/glsl/glsltypes.h
@@ -99,13 +99,27 @@ public:
     virtual bool isLessThan(const Type *other) const;
 };
 
-class GLSL_EXPORT VectorType: public Type, public Scope
+// Type that can be indexed with the [] operator.
+class GLSL_EXPORT IndexType: public Type
+{
+public:
+    IndexType(const Type *indexElementType) : _indexElementType(indexElementType) {}
+
+    const Type *indexElementType() const { return _indexElementType; }
+
+    virtual const IndexType *asIndexType() const { return this; }
+
+private:
+    const Type *_indexElementType;
+};
+
+class GLSL_EXPORT VectorType: public IndexType, public Scope
 {
 public:
     VectorType(const Type *elementType, int dimension)
-        : _elementType(elementType), _dimension(dimension) {}
+        : IndexType(elementType), _dimension(dimension) {}
 
-    const Type *elementType() const { return _elementType; }
+    const Type *elementType() const { return indexElementType(); }
     int dimension() const { return _dimension; }
 
     virtual void add(Symbol *symbol);
@@ -117,7 +131,6 @@ public:
     virtual bool isLessThan(const Type *other) const;
 
 private:
-    const Type *_elementType;
     int _dimension;
     QHash<QString, Symbol *> _members;
 
@@ -127,13 +140,14 @@ private:
     void populateMembers(Engine *engine, const char *components);
 };
 
-class GLSL_EXPORT MatrixType: public Type
+class GLSL_EXPORT MatrixType: public IndexType
 {
 public:
-    MatrixType(const Type *elementType, int columns, int rows)
-        : _elementType(elementType), _columns(columns), _rows(rows) {}
+    MatrixType(const Type *elementType, int columns, int rows, const Type *columnType)
+        : IndexType(columnType), _elementType(elementType), _columns(columns), _rows(rows) {}
 
     const Type *elementType() const { return _elementType; }
+    const Type *columnType() const { return indexElementType(); }
     int columns() const { return _columns; }
     int rows() const { return _rows; }
 
@@ -147,6 +161,19 @@ private:
     int _rows;
 };
 
+class GLSL_EXPORT ArrayType: public IndexType
+{
+public:
+    explicit ArrayType(const Type *elementType)
+        : IndexType(elementType) {}
+
+    const Type *elementType() const { return indexElementType(); }
+
+    virtual const ArrayType *asArrayType() const { return this; }
+    virtual bool isEqualTo(const Type *other) const;
+    virtual bool isLessThan(const Type *other) const;
+};
+
 class GLSL_EXPORT Struct: public Type, public Scope
 {
 public: