diff --git a/src/shared/cplusplus/Control.cpp b/src/shared/cplusplus/Control.cpp
index 28365a625990a73ad7fdd645c5c431165bde82e2..60b310e23e7cf114f54beb3aeb33cb5bf135b097 100644
--- a/src/shared/cplusplus/Control.cpp
+++ b/src/shared/cplusplus/Control.cpp
@@ -54,6 +54,7 @@
 #include "Symbols.h"
 #include "Names.h"
 #include "Array.h"
+#include "TypeMatcher.h"
 #include <map> // ### replace me with LiteralTable
 
 using namespace CPlusPlus;
@@ -80,6 +81,13 @@ template <typename _Array>
 static void delete_array_entries(const _Array &a)
 { delete_array_entries(a.begin(), a.end()); }
 
+template <typename _Tp>
+static void delete_array_entries(const Array<_Tp> &a)
+{
+    for (unsigned i = 0; i < a.size(); ++i)
+        delete a.at(i);
+}
+
 class Control::Data
 {
 public:
@@ -100,13 +108,13 @@ public:
         delete_map_entries(templateNameIds);
 
         // types
-        delete_map_entries(integerTypes);
-        delete_map_entries(floatTypes);
-        delete_map_entries(pointerToMemberTypes);
-        delete_map_entries(pointerTypes);
-        delete_map_entries(referenceTypes);
-        delete_map_entries(arrayTypes);
-        delete_map_entries(namedTypes);
+        delete_array_entries(integerTypes);
+        delete_array_entries(floatTypes);
+        delete_array_entries(pointerToMemberTypes);
+        delete_array_entries(pointerTypes);
+        delete_array_entries(referenceTypes);
+        delete_array_entries(arrayTypes);
+        delete_array_entries(namedTypes);
 
         // symbols
         delete_array_entries(declarations);
@@ -210,66 +218,95 @@ public:
 
     IntegerType *findOrInsertIntegerType(int kind)
     {
-        const int key = int(kind);
-        std::map<int, IntegerType *>::iterator it = integerTypes.lower_bound(key);
-        if (it == integerTypes.end() || it->first != key)
-            it = integerTypes.insert(it, std::make_pair(key, new IntegerType(kind)));
-        return it->second;
+        for (unsigned i = 0; i < integerTypes.size(); ++i) {
+            IntegerType *ty = integerTypes.at(i);
+
+            if (ty->kind() == kind)
+                return ty;
+        }
+
+        IntegerType *ty = new IntegerType(kind);
+        integerTypes.push_back(ty);
+        return ty;
     }
 
     FloatType *findOrInsertFloatType(int kind)
     {
-        const int key = int(kind);
-        std::map<int, FloatType *>::iterator it = floatTypes.lower_bound(key);
-        if (it == floatTypes.end() || it->first != key)
-            it = floatTypes.insert(it, std::make_pair(key, new FloatType(kind)));
-        return it->second;
+        for (unsigned i = 0; i < floatTypes.size(); ++i) {
+            FloatType *ty = floatTypes.at(i);
+
+            if (ty->kind() == kind)
+                return ty;
+        }
+
+        FloatType *ty = new FloatType(kind);
+        floatTypes.push_back(ty);
+        return ty;
     }
 
-    PointerToMemberType *findOrInsertPointerToMemberType(Name *memberName, FullySpecifiedType elementType)
+    PointerToMemberType *findOrInsertPointerToMemberType(Name *memberName, const FullySpecifiedType &elementType)
     {
-        const PointerToMemberTypeKey key(memberName, elementType);
-        std::map<PointerToMemberTypeKey, PointerToMemberType *>::iterator it =
-                pointerToMemberTypes.lower_bound(key);
-        if (it == pointerToMemberTypes.end() || it->first != key)
-            it = pointerToMemberTypes.insert(it, std::make_pair(key, new PointerToMemberType(memberName, elementType)));
-        return it->second;
+        for (unsigned i = 0; i < pointerToMemberTypes.size(); ++i) {
+            PointerToMemberType *ty = pointerToMemberTypes.at(i);
+            if (ty->elementType().match(elementType, &matcher) && matcher.isEqualTo(ty->memberName(), memberName))
+                return ty;
+        }
+
+        PointerToMemberType *ty = new PointerToMemberType(memberName, elementType);
+        pointerToMemberTypes.push_back(ty);
+        return ty;
     }
 
     PointerType *findOrInsertPointerType(const FullySpecifiedType &elementType)
     {
-        std::map<FullySpecifiedType, PointerType *>::iterator it =
-                pointerTypes.lower_bound(elementType);
-        if (it == pointerTypes.end() || it->first != elementType)
-            it = pointerTypes.insert(it, std::make_pair(elementType, new PointerType(elementType)));
-        return it->second;
+        for (unsigned i = 0; i < pointerTypes.size(); ++i) {
+            PointerType *ty = pointerTypes.at(i);
+            if (ty->elementType().match(elementType, &matcher))
+                return ty;
+        }
+
+        PointerType *ty = new PointerType(elementType);
+        pointerTypes.push_back(ty);
+        return ty;
     }
 
     ReferenceType *findOrInsertReferenceType(const FullySpecifiedType &elementType)
     {
-        std::map<FullySpecifiedType, ReferenceType *>::iterator it =
-                referenceTypes.lower_bound(elementType);
-        if (it == referenceTypes.end() || it->first != elementType)
-            it = referenceTypes.insert(it, std::make_pair(elementType, new ReferenceType(elementType)));
-        return it->second;
+        for (unsigned i = 0; i < referenceTypes.size(); ++i) {
+            ReferenceType *ty = referenceTypes.at(i);
+            if (ty->elementType().match(elementType, &matcher))
+                return ty;
+        }
+
+        ReferenceType *ty = new ReferenceType(elementType);
+        referenceTypes.push_back(ty);
+        return ty;
     }
 
-    ArrayType *findOrInsertArrayType(const FullySpecifiedType &elementType, size_t size)
+    ArrayType *findOrInsertArrayType(const FullySpecifiedType &elementType, unsigned size)
     {
-        const ArrayKey key(elementType, size);
-        std::map<ArrayKey, ArrayType *>::iterator it =
-                arrayTypes.lower_bound(key);
-        if (it == arrayTypes.end() || it->first != key)
-            it = arrayTypes.insert(it, std::make_pair(key, new ArrayType(elementType, size)));
-        return it->second;
+        for (unsigned i = 0; i < arrayTypes.size(); ++i) {
+            ArrayType *ty = arrayTypes.at(i);
+            if (ty->size() == size && ty->elementType().match(elementType, &matcher))
+                return ty;
+        }
+
+        ArrayType *ty = new ArrayType(elementType, size);
+        arrayTypes.push_back(ty);
+        return ty;
     }
 
     NamedType *findOrInsertNamedType(Name *name)
     {
-        std::map<Name *, NamedType *>::iterator it = namedTypes.lower_bound(name);
-        if (it == namedTypes.end() || it->first != name)
-            it = namedTypes.insert(it, std::make_pair(name, new NamedType(name)));
-        return it->second;
+        for (unsigned i = 0; i < namedTypes.size(); ++i) {
+            NamedType *ty = namedTypes.at(i);
+            if (matcher.isEqualTo(ty->name(), name))
+                return ty;
+        }
+
+        NamedType *ty = new NamedType(name);
+        namedTypes.push_back(ty);
+        return ty;
     }
 
     Declaration *newDeclaration(unsigned sourceLocation, Name *name)
@@ -484,61 +521,12 @@ public:
         }
     };
 
-    struct ArrayKey {
-        FullySpecifiedType type;
-        size_t size;
-
-        ArrayKey() :
-            size(0)
-        { }
-
-        ArrayKey(const FullySpecifiedType &type, size_t size) :
-            type(type), size(size)
-        { }
-
-        bool operator == (const ArrayKey &other) const
-        { return type == other.type && size == other.size; }
-
-        bool operator != (const ArrayKey &other) const
-        { return ! operator==(other); }
-
-        bool operator < (const ArrayKey &other) const
-        {
-            if (type == other.type)
-                return size < other.size;
-            return type < other.type;
-        }
-    };
-
-    struct PointerToMemberTypeKey {
-        Name *memberName;
-        FullySpecifiedType type;
-
-        PointerToMemberTypeKey()
-            : memberName(0)
-        { }
-
-        PointerToMemberTypeKey(Name *memberName, FullySpecifiedType type)
-            : memberName(memberName), type(type)
-        { }
-
-        bool operator == (const PointerToMemberTypeKey &other) const
-        { return memberName == other.memberName && type == other.type; }
-
-        bool operator != (const PointerToMemberTypeKey &other) const
-        { return ! operator==(other); }
-
-        bool operator < (const PointerToMemberTypeKey &other) const
-        {
-            if (memberName == other.memberName)
-                return type < other.type;
-            return memberName < other.memberName;
-        }
-    };
-
     Control *control;
     TranslationUnit *translationUnit;
     DiagnosticClient *diagnosticClient;
+
+    TypeMatcher matcher;
+
     LiteralTable<Identifier> identifiers;
     LiteralTable<StringLiteral> stringLiterals;
     LiteralTable<NumericLiteral> numericLiterals;
@@ -556,13 +544,13 @@ public:
 
     // types
     VoidType voidType;
-    std::map<int, IntegerType *> integerTypes;
-    std::map<int, FloatType *> floatTypes;
-    std::map<PointerToMemberTypeKey, PointerToMemberType *> pointerToMemberTypes;
-    std::map<FullySpecifiedType, PointerType *> pointerTypes;
-    std::map<FullySpecifiedType, ReferenceType *> referenceTypes;
-    std::map<ArrayKey, ArrayType *> arrayTypes;
-    std::map<Name *, NamedType *> namedTypes;
+    Array<IntegerType *> integerTypes;
+    Array<FloatType *> floatTypes;
+    Array<PointerToMemberType *> pointerToMemberTypes;
+    Array<PointerType *> pointerTypes;
+    Array<ReferenceType *> referenceTypes;
+    Array<ArrayType *> arrayTypes;
+    Array<NamedType *> namedTypes;
 
     // symbols
     std::vector<Declaration *> declarations;
@@ -723,7 +711,7 @@ IntegerType *Control::integerType(int kind)
 FloatType *Control::floatType(int kind)
 { return d->findOrInsertFloatType(kind); }
 
-PointerToMemberType *Control::pointerToMemberType(Name *memberName, FullySpecifiedType elementType)
+PointerToMemberType *Control::pointerToMemberType(Name *memberName, const FullySpecifiedType &elementType)
 { return d->findOrInsertPointerToMemberType(memberName, elementType); }
 
 PointerType *Control::pointerType(const FullySpecifiedType &elementType)
@@ -732,7 +720,7 @@ PointerType *Control::pointerType(const FullySpecifiedType &elementType)
 ReferenceType *Control::referenceType(const FullySpecifiedType &elementType)
 { return d->findOrInsertReferenceType(elementType); }
 
-ArrayType *Control::arrayType(const FullySpecifiedType &elementType, size_t size)
+ArrayType *Control::arrayType(const FullySpecifiedType &elementType, unsigned size)
 { return d->findOrInsertArrayType(elementType, size); }
 
 NamedType *Control::namedType(Name *name)
diff --git a/src/shared/cplusplus/Control.h b/src/shared/cplusplus/Control.h
index 4d6cc73ce99ae154d29cf6ba0333d9ab68eda34b..53203f832f3172d7a3337fc8f61bfb14fa83a6cc 100644
--- a/src/shared/cplusplus/Control.h
+++ b/src/shared/cplusplus/Control.h
@@ -102,7 +102,7 @@ public:
 
     /// Returns a Type object of type PointertoMemberType.
     PointerToMemberType *pointerToMemberType(Name *memberName,
-                                             FullySpecifiedType elementType);
+                                             const FullySpecifiedType &elementType);
 
     /// Returns a Type object of type PointerType.
     PointerType *pointerType(const FullySpecifiedType &elementType);
@@ -111,7 +111,7 @@ public:
     ReferenceType *referenceType(const FullySpecifiedType &elementType);
 
     /// Retruns a Type object of type ArrayType.
-    ArrayType *arrayType(const FullySpecifiedType &elementType, size_t size = 0);
+    ArrayType *arrayType(const FullySpecifiedType &elementType, unsigned size = 0);
 
     /// Returns a Type object of type NamedType.
     NamedType *namedType(Name *name);
diff --git a/src/shared/cplusplus/CoreTypes.cpp b/src/shared/cplusplus/CoreTypes.cpp
index ed9a9c00611209b7860874bd81917332ae5b439c..9bdd17a827f0a3fac2e275d53d62320646024b32 100644
--- a/src/shared/cplusplus/CoreTypes.cpp
+++ b/src/shared/cplusplus/CoreTypes.cpp
@@ -90,7 +90,7 @@ bool VoidType::matchType0(const Type *otherType, TypeMatcher *matcher) const
     return false;
 }
 
-PointerToMemberType::PointerToMemberType(Name *memberName, FullySpecifiedType elementType)
+PointerToMemberType::PointerToMemberType(Name *memberName, const FullySpecifiedType &elementType)
     : _memberName(memberName),
       _elementType(elementType)
 { }
@@ -241,7 +241,7 @@ bool FloatType::isEqualTo(const Type *other) const
     return _kind == o->_kind;
 }
 
-ArrayType::ArrayType(const FullySpecifiedType &elementType, size_t size)
+ArrayType::ArrayType(const FullySpecifiedType &elementType, unsigned size)
     : _elementType(elementType), _size(size)
 { }
 
@@ -272,7 +272,7 @@ bool ArrayType::matchType0(const Type *otherType, TypeMatcher *matcher) const
 FullySpecifiedType ArrayType::elementType() const
 { return _elementType; }
 
-size_t ArrayType::size() const
+unsigned ArrayType::size() const
 { return _size; }
 
 NamedType::NamedType(Name *name)
diff --git a/src/shared/cplusplus/CoreTypes.h b/src/shared/cplusplus/CoreTypes.h
index ab729be28f64c8339149df26974497e0fde373dd..dc70f06ddf6f3d96794b67a67519fcb8343568ff 100644
--- a/src/shared/cplusplus/CoreTypes.h
+++ b/src/shared/cplusplus/CoreTypes.h
@@ -186,7 +186,7 @@ private:
 class CPLUSPLUS_EXPORT PointerToMemberType: public Type
 {
 public:
-    PointerToMemberType(Name *memberName, FullySpecifiedType elementType);
+    PointerToMemberType(Name *memberName, const FullySpecifiedType &elementType);
     virtual ~PointerToMemberType();
 
     Name *memberName() const;
@@ -236,11 +236,11 @@ private:
 class CPLUSPLUS_EXPORT ArrayType: public Type
 {
 public:
-    ArrayType(const FullySpecifiedType &elementType, size_t size);
+    ArrayType(const FullySpecifiedType &elementType, unsigned size);
     virtual ~ArrayType();
 
     FullySpecifiedType elementType() const;
-    size_t size() const;
+    unsigned size() const;
 
     virtual bool isEqualTo(const Type *other) const;
 
@@ -256,7 +256,7 @@ protected:
 
 private:
     FullySpecifiedType _elementType;
-    size_t _size;
+    unsigned _size;
 };
 
 class CPLUSPLUS_EXPORT NamedType: public Type
diff --git a/src/shared/cplusplus/Semantic.cpp b/src/shared/cplusplus/Semantic.cpp
index 23e2fa2c95f108d48a17b96fb91ee3dd89d57ee3..74d870a91c0429bf0b068a0bd43e15d7e58091e7 100644
--- a/src/shared/cplusplus/Semantic.cpp
+++ b/src/shared/cplusplus/Semantic.cpp
@@ -131,11 +131,11 @@ FullySpecifiedType Semantic::check(SpecifierListAST *specifier, Scope *scope)
 void Semantic::check(DeclarationAST *declaration, Scope *scope, TemplateParameters *templateParameters)
 { d->checkDeclaration->check(declaration, scope, templateParameters); }
 
-FullySpecifiedType Semantic::check(DeclaratorAST *declarator, FullySpecifiedType type,
+FullySpecifiedType Semantic::check(DeclaratorAST *declarator, const FullySpecifiedType &type,
                                    Scope *scope, Name **name)
 { return d->checkDeclarator->check(declarator, type, scope, name); }
 
-FullySpecifiedType Semantic::check(PtrOperatorListAST *ptrOperators, FullySpecifiedType type,
+FullySpecifiedType Semantic::check(PtrOperatorListAST *ptrOperators, const FullySpecifiedType &type,
                                    Scope *scope)
 { return d->checkDeclarator->check(ptrOperators, type, scope); }
 
diff --git a/src/shared/cplusplus/Semantic.h b/src/shared/cplusplus/Semantic.h
index 4a2ebfc2fbd0013f36d6a4838aea2c5ea2e9df96..f6a4e528f48e22b4f667be1cc895c525ae069952 100644
--- a/src/shared/cplusplus/Semantic.h
+++ b/src/shared/cplusplus/Semantic.h
@@ -69,10 +69,10 @@ public:
 
     FullySpecifiedType check(SpecifierListAST *specifier, Scope *scope);
 
-    FullySpecifiedType check(DeclaratorAST *declarator, FullySpecifiedType type,
+    FullySpecifiedType check(DeclaratorAST *declarator, const FullySpecifiedType &type,
                              Scope *scope, Name **name = 0); // ### ugly
 
-    FullySpecifiedType check(PtrOperatorListAST *ptrOperators, FullySpecifiedType type,
+    FullySpecifiedType check(PtrOperatorListAST *ptrOperators, const FullySpecifiedType &type,
                              Scope *scope);
 
     FullySpecifiedType check(ObjCMethodPrototypeAST *methodPrototype, Scope *scope);
diff --git a/src/shared/cplusplus/TypeMatcher.h b/src/shared/cplusplus/TypeMatcher.h
index bad91af5d2e8a499b2346b7169902ab5f95d0c18..50a7871cdd7218061184fd5ac24e992ff1e59b2f 100644
--- a/src/shared/cplusplus/TypeMatcher.h
+++ b/src/shared/cplusplus/TypeMatcher.h
@@ -64,7 +64,6 @@ public:
     virtual bool match(const ObjCForwardProtocolDeclaration *type, const ObjCForwardProtocolDeclaration *otherType);
     virtual bool match(const ObjCMethod *type, const ObjCMethod *otherType);
 
-protected:
     bool isEqualTo(const Name *name, const Name *otherName) const;
 };