diff --git a/src/libs/cplusplus/CheckUndefinedSymbols.cpp b/src/libs/cplusplus/CheckUndefinedSymbols.cpp
index 5d996579eed5834ed3a81b84e4f8fc32e1f2de27..6010e4283ee39c43a88c4a89d29c7f5a06c489bf 100644
--- a/src/libs/cplusplus/CheckUndefinedSymbols.cpp
+++ b/src/libs/cplusplus/CheckUndefinedSymbols.cpp
@@ -522,11 +522,13 @@ bool CheckUndefinedSymbols::visit(ObjCProtocolRefsAST *ast)
 bool CheckUndefinedSymbols::visit(ObjCPropertyDeclarationAST *ast)
 {
     for (List<ObjCPropertyDeclaration *> *iter = ast->symbols; iter; iter = iter->next) {
-        if (Name *getterName = iter->value->getterName())
-            ; // FIXME: resolve the symbol for the name, and check its signature.
+        if (Name *getterName = iter->value->getterName()) {
+            // FIXME: resolve the symbol for the name, and check its signature.
+        }
 
-        if (Name *setterName = iter->value->setterName())
-            ; // FIXME: resolve the symbol for the name, and check its signature.
+        if (Name *setterName = iter->value->setterName()) {
+            // FIXME: resolve the symbol for the name, and check its signature.
+        }
     }
 
     return false;
diff --git a/src/shared/cplusplus/AST.cpp b/src/shared/cplusplus/AST.cpp
index 38f3050b008dcd37af455ccb99738d871ae9546f..1e6cae8969e49647a7e8580cea8707c73b4cbfe0 100644
--- a/src/shared/cplusplus/AST.cpp
+++ b/src/shared/cplusplus/AST.cpp
@@ -48,6 +48,7 @@
 
 #include "AST.h"
 #include "ASTVisitor.h"
+#include "ASTMatcher.h"
 #include "MemoryPool.h"
 
 #include <cassert>
@@ -69,6 +70,22 @@ void AST::accept(ASTVisitor *visitor)
     visitor->postVisit(this);
 }
 
+bool AST::match(AST *ast, AST *pattern, ASTMatcher *matcher)
+{
+    if (ast == pattern)
+        return true;
+
+    else if (! ast || ! pattern)
+        return false;
+
+    return ast->match(pattern, matcher);
+}
+
+bool AST::match(AST *pattern, ASTMatcher *matcher)
+{
+    return match0(pattern, matcher);
+}
+
 unsigned AttributeSpecifierAST::firstToken() const
 {
     return attribute_token;
diff --git a/src/shared/cplusplus/AST.h b/src/shared/cplusplus/AST.h
index 2a1c2d6ef035bef2bee63ba2ffbc92f0d0f1215f..d30858f0507242ceb67db4e36bd9071992e1b08f 100644
--- a/src/shared/cplusplus/AST.h
+++ b/src/shared/cplusplus/AST.h
@@ -120,6 +120,26 @@ public:
             accept(it->value, visitor);
     }
 
+    static bool match(AST *ast, AST *pattern, ASTMatcher *matcher);
+    bool match(AST *pattern, ASTMatcher *matcher);
+
+    template <typename _Tp>
+    static bool match(List<_Tp> *it, List<_Tp> *patternIt, ASTMatcher *matcher)
+    {
+        while (it && patternIt) {
+            if (! match(it->value, patternIt->value, matcher))
+                return false;
+
+            it = it->next;
+            patternIt = patternIt->next;
+        }
+
+        if (! it && ! patternIt)
+            return true;
+
+        return false;
+    }
+
     virtual unsigned firstToken() const = 0;
     virtual unsigned lastToken() const = 0;
 
@@ -255,8 +275,10 @@ public:
     virtual UsingAST *asUsing() { return 0; }
     virtual UsingDirectiveAST *asUsingDirective() { return 0; }
     virtual WhileStatementAST *asWhileStatement() { return 0; }
+
 protected:
     virtual void accept0(ASTVisitor *visitor) = 0;
+    virtual bool match0(AST *, ASTMatcher *) = 0;
 };
 
 class CPLUSPLUS_EXPORT SpecifierAST: public AST
@@ -278,6 +300,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT AttributeSpecifierAST: public SpecifierAST
@@ -298,6 +321,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT AttributeAST: public AST
@@ -317,6 +341,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT TypeofSpecifierAST: public SpecifierAST
@@ -335,6 +360,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT StatementAST: public AST
@@ -386,6 +412,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT SimpleDeclarationAST: public DeclarationAST
@@ -407,6 +434,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT EmptyDeclarationAST: public DeclarationAST
@@ -422,6 +450,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT AccessDeclarationAST: public DeclarationAST
@@ -439,6 +468,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT AsmDefinitionAST: public DeclarationAST
@@ -460,6 +490,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT BaseSpecifierAST: public AST
@@ -480,6 +511,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT CompoundLiteralAST: public ExpressionAST
@@ -498,6 +530,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT QtMethodAST: public ExpressionAST
@@ -516,6 +549,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT BinaryExpressionAST: public ExpressionAST
@@ -533,6 +567,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT CastExpressionAST: public ExpressionAST
@@ -551,6 +586,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ClassSpecifierAST: public SpecifierAST
@@ -576,6 +612,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT CaseStatementAST: public StatementAST
@@ -594,6 +631,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT CompoundStatementAST: public StatementAST
@@ -614,6 +652,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ConditionAST: public ExpressionAST
@@ -630,6 +669,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ConditionalExpressionAST: public ExpressionAST
@@ -649,6 +689,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT CppCastExpressionAST: public ExpressionAST
@@ -670,6 +711,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT CtorInitializerAST: public AST
@@ -686,6 +728,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT DeclarationStatementAST: public StatementAST
@@ -701,6 +744,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT DeclaratorIdAST: public CoreDeclaratorAST
@@ -716,6 +760,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT NestedDeclaratorAST: public CoreDeclaratorAST
@@ -733,6 +778,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT FunctionDeclaratorAST: public PostfixDeclaratorAST
@@ -756,6 +802,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ArrayDeclaratorAST: public PostfixDeclaratorAST
@@ -773,6 +820,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT DeleteExpressionAST: public ExpressionAST
@@ -792,6 +840,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT DoStatementAST: public StatementAST
@@ -813,6 +862,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT NamedTypeSpecifierAST: public SpecifierAST
@@ -828,6 +878,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ElaboratedTypeSpecifierAST: public SpecifierAST
@@ -844,6 +895,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT EnumSpecifierAST: public SpecifierAST
@@ -863,6 +915,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT EnumeratorAST: public AST
@@ -880,6 +933,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ExceptionDeclarationAST: public DeclarationAST
@@ -897,6 +951,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ExceptionSpecificationAST: public AST
@@ -916,6 +971,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ExpressionOrDeclarationStatementAST: public StatementAST
@@ -932,6 +988,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ExpressionStatementAST: public StatementAST
@@ -948,6 +1005,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT FunctionDefinitionAST: public DeclarationAST
@@ -970,6 +1028,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ForeachStatementAST: public StatementAST
@@ -998,6 +1057,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ForStatementAST: public StatementAST
@@ -1023,6 +1083,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT IfStatementAST: public StatementAST
@@ -1047,6 +1108,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ArrayInitializerAST: public ExpressionAST
@@ -1064,6 +1126,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT LabeledStatementAST: public StatementAST
@@ -1081,6 +1144,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT LinkageBodyAST: public DeclarationAST
@@ -1097,6 +1161,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT LinkageSpecificationAST: public DeclarationAST
@@ -1114,6 +1179,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT MemInitializerAST: public AST
@@ -1132,6 +1198,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT NameAST: public ExpressionAST
@@ -1158,6 +1225,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT QualifiedNameAST: public NameAST
@@ -1175,6 +1243,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT OperatorFunctionIdAST: public NameAST
@@ -1191,6 +1260,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ConversionFunctionIdAST: public NameAST
@@ -1208,6 +1278,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT SimpleNameAST: public NameAST
@@ -1223,6 +1294,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT DestructorNameAST: public NameAST
@@ -1239,6 +1311,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT TemplateIdAST: public NameAST
@@ -1257,6 +1330,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT NamespaceAST: public DeclarationAST
@@ -1278,6 +1352,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT NamespaceAliasDefinitionAST: public DeclarationAST
@@ -1297,6 +1372,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT NewPlacementAST: public AST
@@ -1314,6 +1390,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT NewArrayDeclaratorAST: public AST
@@ -1331,6 +1408,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT NewExpressionAST: public ExpressionAST
@@ -1356,6 +1434,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT NewInitializerAST: public AST
@@ -1373,6 +1452,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT NewTypeIdAST: public AST
@@ -1390,6 +1470,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT OperatorAST: public AST
@@ -1407,6 +1488,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ParameterDeclarationAST: public DeclarationAST
@@ -1428,6 +1510,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ParameterDeclarationClauseAST: public AST
@@ -1444,6 +1527,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT PostfixAST: public AST
@@ -1467,6 +1551,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ArrayAccessAST: public PostfixAST
@@ -1484,6 +1569,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT PostIncrDecrAST: public PostfixAST
@@ -1499,6 +1585,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT MemberAccessAST: public PostfixAST
@@ -1516,6 +1603,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT TypeidExpressionAST: public ExpressionAST
@@ -1534,6 +1622,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT TypenameCallExpressionAST: public ExpressionAST
@@ -1553,6 +1642,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT TypeConstructorCallAST: public ExpressionAST
@@ -1571,6 +1661,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT PostfixExpressionAST: public ExpressionAST
@@ -1587,6 +1678,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT PtrOperatorAST: public AST
@@ -1611,6 +1703,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT PointerAST: public PtrOperatorAST
@@ -1627,6 +1720,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ReferenceAST: public PtrOperatorAST
@@ -1642,6 +1736,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT BreakStatementAST: public StatementAST
@@ -1658,6 +1753,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ContinueStatementAST: public StatementAST
@@ -1674,6 +1770,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT GotoStatementAST: public StatementAST
@@ -1691,6 +1788,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ReturnStatementAST: public StatementAST
@@ -1708,6 +1806,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT SizeofExpressionAST: public ExpressionAST
@@ -1726,6 +1825,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT NumericLiteralAST: public ExpressionAST
@@ -1741,6 +1841,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT BoolLiteralAST: public ExpressionAST
@@ -1756,6 +1857,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ThisExpressionAST: public ExpressionAST
@@ -1771,6 +1873,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT NestedExpressionAST: public ExpressionAST
@@ -1788,6 +1891,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT StringLiteralAST: public ExpressionAST
@@ -1804,6 +1908,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT SwitchStatementAST: public StatementAST
@@ -1826,6 +1931,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT TemplateDeclarationAST: public DeclarationAST
@@ -1846,6 +1952,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ThrowExpressionAST: public ExpressionAST
@@ -1862,6 +1969,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT TranslationUnitAST: public AST
@@ -1877,6 +1985,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT TryBlockStatementAST: public StatementAST
@@ -1894,6 +2003,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT CatchClauseAST: public StatementAST
@@ -1916,6 +2026,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT TypeIdAST: public ExpressionAST
@@ -1932,6 +2043,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT TypenameTypeParameterAST: public DeclarationAST
@@ -1953,6 +2065,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT TemplateTypeParameterAST: public DeclarationAST
@@ -1978,6 +2091,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT UnaryExpressionAST: public ExpressionAST
@@ -1994,6 +2108,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT UsingAST: public DeclarationAST
@@ -2015,6 +2130,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT UsingDirectiveAST: public DeclarationAST
@@ -2036,6 +2152,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT WhileStatementAST: public StatementAST
@@ -2058,6 +2175,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ObjCClassForwardDeclarationAST: public DeclarationAST
@@ -2079,6 +2197,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ObjCClassDeclarationAST: public DeclarationAST
@@ -2109,6 +2228,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ObjCProtocolForwardDeclarationAST: public DeclarationAST
@@ -2130,6 +2250,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ObjCProtocolDeclarationAST: public DeclarationAST
@@ -2153,6 +2274,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ObjCProtocolRefsAST: public AST
@@ -2170,6 +2292,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ObjCMessageArgumentAST: public AST
@@ -2185,6 +2308,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ObjCMessageExpressionAST: public ExpressionAST
@@ -2204,6 +2328,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ObjCProtocolExpressionAST: public ExpressionAST
@@ -2222,6 +2347,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ObjCTypeNameAST: public AST
@@ -2240,6 +2366,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ObjCEncodeExpressionAST: public ExpressionAST
@@ -2256,6 +2383,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ObjCSelectorAST: public AST
@@ -2281,6 +2409,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ObjCSelectorArgumentAST: public AST
@@ -2297,6 +2426,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ObjCSelectorWithArgumentsAST: public ObjCSelectorAST
@@ -2312,6 +2442,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ObjCSelectorExpressionAST: public ExpressionAST
@@ -2330,6 +2461,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ObjCInstanceVariablesDeclarationAST: public AST
@@ -2347,6 +2479,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ObjCVisibilityDeclarationAST: public DeclarationAST
@@ -2362,6 +2495,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ObjCPropertyAttributeAST: public AST
@@ -2379,6 +2513,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ObjCPropertyDeclarationAST: public DeclarationAST
@@ -2402,6 +2537,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ObjCMessageArgumentDeclarationAST: public NameAST
@@ -2422,6 +2558,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ObjCMethodPrototypeAST: public AST
@@ -2445,6 +2582,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ObjCMethodDeclarationAST: public DeclarationAST
@@ -2462,6 +2600,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ObjCSynthesizedPropertyAST: public AST
@@ -2479,6 +2618,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ObjCSynthesizedPropertiesDeclarationAST: public DeclarationAST
@@ -2496,6 +2636,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ObjCDynamicPropertiesDeclarationAST: public DeclarationAST
@@ -2513,6 +2654,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ObjCFastEnumerationAST: public StatementAST
@@ -2543,6 +2685,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT ObjCSynchronizedStatementAST: public StatementAST
@@ -2562,6 +2705,7 @@ public:
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 } // end of namespace CPlusPlus
diff --git a/src/shared/cplusplus/ASTMatch0.cpp b/src/shared/cplusplus/ASTMatch0.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a6522b5407f9234b324c0029f1925e6413b5bbc0
--- /dev/null
+++ b/src/shared/cplusplus/ASTMatch0.cpp
@@ -0,0 +1,1628 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "AST.h"
+#include "ASTMatcher.h"
+
+using namespace CPlusPlus;
+
+bool SimpleSpecifierAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (SimpleSpecifierAST *_other = pattern->asSimpleSpecifier()) {
+        if (! matcher->match(this, _other))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool AttributeSpecifierAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (AttributeSpecifierAST *_other = pattern->asAttributeSpecifier()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(attribute_list, _other->attribute_list, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool AttributeAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (AttributeAST *_other = pattern->asAttribute()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(expression_list, _other->expression_list, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool TypeofSpecifierAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (TypeofSpecifierAST *_other = pattern->asTypeofSpecifier()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(expression, _other->expression, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool DeclaratorAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (DeclaratorAST *_other = pattern->asDeclarator()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(attribute_list, _other->attribute_list, matcher))
+            return false;
+        if (! match(ptr_operator_list, _other->ptr_operator_list, matcher))
+            return false;
+        if (! match(core_declarator, _other->core_declarator, matcher))
+            return false;
+        if (! match(postfix_declarator_list, _other->postfix_declarator_list, matcher))
+            return false;
+        if (! match(post_attribute_list, _other->post_attribute_list, matcher))
+            return false;
+        if (! match(initializer, _other->initializer, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool SimpleDeclarationAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (SimpleDeclarationAST *_other = pattern->asSimpleDeclaration()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(decl_specifier_list, _other->decl_specifier_list, matcher))
+            return false;
+        if (! match(declarator_list, _other->declarator_list, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool EmptyDeclarationAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (EmptyDeclarationAST *_other = pattern->asEmptyDeclaration()) {
+        if (! matcher->match(this, _other))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool AccessDeclarationAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (AccessDeclarationAST *_other = pattern->asAccessDeclaration()) {
+        if (! matcher->match(this, _other))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool AsmDefinitionAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (AsmDefinitionAST *_other = pattern->asAsmDefinition()) {
+        if (! matcher->match(this, _other))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool BaseSpecifierAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (BaseSpecifierAST *_other = pattern->asBaseSpecifier()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(name, _other->name, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool CompoundLiteralAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (CompoundLiteralAST *_other = pattern->asCompoundLiteral()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(type_id, _other->type_id, matcher))
+            return false;
+        if (! match(initializer, _other->initializer, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool QtMethodAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (QtMethodAST *_other = pattern->asQtMethod()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(declarator, _other->declarator, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool BinaryExpressionAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (BinaryExpressionAST *_other = pattern->asBinaryExpression()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(left_expression, _other->left_expression, matcher))
+            return false;
+        if (! match(right_expression, _other->right_expression, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool CastExpressionAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (CastExpressionAST *_other = pattern->asCastExpression()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(type_id, _other->type_id, matcher))
+            return false;
+        if (! match(expression, _other->expression, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ClassSpecifierAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ClassSpecifierAST *_other = pattern->asClassSpecifier()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(attribute_list, _other->attribute_list, matcher))
+            return false;
+        if (! match(name, _other->name, matcher))
+            return false;
+        if (! match(base_clause_list, _other->base_clause_list, matcher))
+            return false;
+        if (! match(member_specifier_list, _other->member_specifier_list, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool CaseStatementAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (CaseStatementAST *_other = pattern->asCaseStatement()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(expression, _other->expression, matcher))
+            return false;
+        if (! match(statement, _other->statement, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool CompoundStatementAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (CompoundStatementAST *_other = pattern->asCompoundStatement()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(statement_list, _other->statement_list, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ConditionAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ConditionAST *_other = pattern->asCondition()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(type_specifier_list, _other->type_specifier_list, matcher))
+            return false;
+        if (! match(declarator, _other->declarator, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ConditionalExpressionAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ConditionalExpressionAST *_other = pattern->asConditionalExpression()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(condition, _other->condition, matcher))
+            return false;
+        if (! match(left_expression, _other->left_expression, matcher))
+            return false;
+        if (! match(right_expression, _other->right_expression, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool CppCastExpressionAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (CppCastExpressionAST *_other = pattern->asCppCastExpression()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(type_id, _other->type_id, matcher))
+            return false;
+        if (! match(expression, _other->expression, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool CtorInitializerAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (CtorInitializerAST *_other = pattern->asCtorInitializer()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(member_initializer_list, _other->member_initializer_list, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool DeclarationStatementAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (DeclarationStatementAST *_other = pattern->asDeclarationStatement()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(declaration, _other->declaration, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool DeclaratorIdAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (DeclaratorIdAST *_other = pattern->asDeclaratorId()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(name, _other->name, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool NestedDeclaratorAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (NestedDeclaratorAST *_other = pattern->asNestedDeclarator()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(declarator, _other->declarator, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool FunctionDeclaratorAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (FunctionDeclaratorAST *_other = pattern->asFunctionDeclarator()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(parameters, _other->parameters, matcher))
+            return false;
+        if (! match(cv_qualifier_list, _other->cv_qualifier_list, matcher))
+            return false;
+        if (! match(exception_specification, _other->exception_specification, matcher))
+            return false;
+        if (! match(as_cpp_initializer, _other->as_cpp_initializer, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ArrayDeclaratorAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ArrayDeclaratorAST *_other = pattern->asArrayDeclarator()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(expression, _other->expression, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool DeleteExpressionAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (DeleteExpressionAST *_other = pattern->asDeleteExpression()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(expression, _other->expression, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool DoStatementAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (DoStatementAST *_other = pattern->asDoStatement()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(statement, _other->statement, matcher))
+            return false;
+        if (! match(expression, _other->expression, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool NamedTypeSpecifierAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (NamedTypeSpecifierAST *_other = pattern->asNamedTypeSpecifier()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(name, _other->name, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ElaboratedTypeSpecifierAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ElaboratedTypeSpecifierAST *_other = pattern->asElaboratedTypeSpecifier()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(name, _other->name, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool EnumSpecifierAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (EnumSpecifierAST *_other = pattern->asEnumSpecifier()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(name, _other->name, matcher))
+            return false;
+        if (! match(enumerator_list, _other->enumerator_list, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool EnumeratorAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (EnumeratorAST *_other = pattern->asEnumerator()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(expression, _other->expression, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ExceptionDeclarationAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ExceptionDeclarationAST *_other = pattern->asExceptionDeclaration()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(type_specifier_list, _other->type_specifier_list, matcher))
+            return false;
+        if (! match(declarator, _other->declarator, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ExceptionSpecificationAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ExceptionSpecificationAST *_other = pattern->asExceptionSpecification()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(type_id_list, _other->type_id_list, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ExpressionOrDeclarationStatementAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ExpressionOrDeclarationStatementAST *_other = pattern->asExpressionOrDeclarationStatement()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(expression, _other->expression, matcher))
+            return false;
+        if (! match(declaration, _other->declaration, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ExpressionStatementAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ExpressionStatementAST *_other = pattern->asExpressionStatement()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(expression, _other->expression, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool FunctionDefinitionAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (FunctionDefinitionAST *_other = pattern->asFunctionDefinition()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(decl_specifier_list, _other->decl_specifier_list, matcher))
+            return false;
+        if (! match(declarator, _other->declarator, matcher))
+            return false;
+        if (! match(ctor_initializer, _other->ctor_initializer, matcher))
+            return false;
+        if (! match(function_body, _other->function_body, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ForeachStatementAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ForeachStatementAST *_other = pattern->asForeachStatement()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(type_specifier_list, _other->type_specifier_list, matcher))
+            return false;
+        if (! match(declarator, _other->declarator, matcher))
+            return false;
+        if (! match(initializer, _other->initializer, matcher))
+            return false;
+        if (! match(expression, _other->expression, matcher))
+            return false;
+        if (! match(statement, _other->statement, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ForStatementAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ForStatementAST *_other = pattern->asForStatement()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(initializer, _other->initializer, matcher))
+            return false;
+        if (! match(condition, _other->condition, matcher))
+            return false;
+        if (! match(expression, _other->expression, matcher))
+            return false;
+        if (! match(statement, _other->statement, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool IfStatementAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (IfStatementAST *_other = pattern->asIfStatement()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(condition, _other->condition, matcher))
+            return false;
+        if (! match(statement, _other->statement, matcher))
+            return false;
+        if (! match(else_statement, _other->else_statement, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ArrayInitializerAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ArrayInitializerAST *_other = pattern->asArrayInitializer()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(expression_list, _other->expression_list, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool LabeledStatementAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (LabeledStatementAST *_other = pattern->asLabeledStatement()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(statement, _other->statement, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool LinkageBodyAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (LinkageBodyAST *_other = pattern->asLinkageBody()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(declaration_list, _other->declaration_list, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool LinkageSpecificationAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (LinkageSpecificationAST *_other = pattern->asLinkageSpecification()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(declaration, _other->declaration, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool MemInitializerAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (MemInitializerAST *_other = pattern->asMemInitializer()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(name, _other->name, matcher))
+            return false;
+        if (! match(expression, _other->expression, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool NestedNameSpecifierAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (NestedNameSpecifierAST *_other = pattern->asNestedNameSpecifier()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(class_or_namespace_name, _other->class_or_namespace_name, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool QualifiedNameAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (QualifiedNameAST *_other = pattern->asQualifiedName()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(nested_name_specifier_list, _other->nested_name_specifier_list, matcher))
+            return false;
+        if (! match(unqualified_name, _other->unqualified_name, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool OperatorFunctionIdAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (OperatorFunctionIdAST *_other = pattern->asOperatorFunctionId()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(op, _other->op, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ConversionFunctionIdAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ConversionFunctionIdAST *_other = pattern->asConversionFunctionId()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(type_specifier_list, _other->type_specifier_list, matcher))
+            return false;
+        if (! match(ptr_operator_list, _other->ptr_operator_list, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool SimpleNameAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (SimpleNameAST *_other = pattern->asSimpleName()) {
+        if (! matcher->match(this, _other))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool DestructorNameAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (DestructorNameAST *_other = pattern->asDestructorName()) {
+        if (! matcher->match(this, _other))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool TemplateIdAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (TemplateIdAST *_other = pattern->asTemplateId()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(template_argument_list, _other->template_argument_list, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool NamespaceAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (NamespaceAST *_other = pattern->asNamespace()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(attribute_list, _other->attribute_list, matcher))
+            return false;
+        if (! match(linkage_body, _other->linkage_body, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool NamespaceAliasDefinitionAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (NamespaceAliasDefinitionAST *_other = pattern->asNamespaceAliasDefinition()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(name, _other->name, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool NewPlacementAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (NewPlacementAST *_other = pattern->asNewPlacement()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(expression_list, _other->expression_list, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool NewArrayDeclaratorAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (NewArrayDeclaratorAST *_other = pattern->asNewArrayDeclarator()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(expression, _other->expression, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool NewExpressionAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (NewExpressionAST *_other = pattern->asNewExpression()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(new_placement, _other->new_placement, matcher))
+            return false;
+        if (! match(type_id, _other->type_id, matcher))
+            return false;
+        if (! match(new_type_id, _other->new_type_id, matcher))
+            return false;
+        if (! match(new_initializer, _other->new_initializer, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool NewInitializerAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (NewInitializerAST *_other = pattern->asNewInitializer()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(expression, _other->expression, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool NewTypeIdAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (NewTypeIdAST *_other = pattern->asNewTypeId()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(type_specifier_list, _other->type_specifier_list, matcher))
+            return false;
+        if (! match(ptr_operator_list, _other->ptr_operator_list, matcher))
+            return false;
+        if (! match(new_array_declarator_list, _other->new_array_declarator_list, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool OperatorAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (OperatorAST *_other = pattern->asOperator()) {
+        if (! matcher->match(this, _other))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ParameterDeclarationAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ParameterDeclarationAST *_other = pattern->asParameterDeclaration()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(type_specifier_list, _other->type_specifier_list, matcher))
+            return false;
+        if (! match(declarator, _other->declarator, matcher))
+            return false;
+        if (! match(expression, _other->expression, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ParameterDeclarationClauseAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ParameterDeclarationClauseAST *_other = pattern->asParameterDeclarationClause()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(parameter_declaration_list, _other->parameter_declaration_list, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool CallAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (CallAST *_other = pattern->asCall()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(expression_list, _other->expression_list, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ArrayAccessAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ArrayAccessAST *_other = pattern->asArrayAccess()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(expression, _other->expression, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool PostIncrDecrAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (PostIncrDecrAST *_other = pattern->asPostIncrDecr()) {
+        if (! matcher->match(this, _other))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool MemberAccessAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (MemberAccessAST *_other = pattern->asMemberAccess()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(member_name, _other->member_name, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool TypeidExpressionAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (TypeidExpressionAST *_other = pattern->asTypeidExpression()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(expression, _other->expression, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool TypenameCallExpressionAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (TypenameCallExpressionAST *_other = pattern->asTypenameCallExpression()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(name, _other->name, matcher))
+            return false;
+        if (! match(expression_list, _other->expression_list, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool TypeConstructorCallAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (TypeConstructorCallAST *_other = pattern->asTypeConstructorCall()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(type_specifier_list, _other->type_specifier_list, matcher))
+            return false;
+        if (! match(expression_list, _other->expression_list, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool PostfixExpressionAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (PostfixExpressionAST *_other = pattern->asPostfixExpression()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(base_expression, _other->base_expression, matcher))
+            return false;
+        if (! match(postfix_expression_list, _other->postfix_expression_list, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool PointerToMemberAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (PointerToMemberAST *_other = pattern->asPointerToMember()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(nested_name_specifier_list, _other->nested_name_specifier_list, matcher))
+            return false;
+        if (! match(cv_qualifier_list, _other->cv_qualifier_list, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool PointerAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (PointerAST *_other = pattern->asPointer()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(cv_qualifier_list, _other->cv_qualifier_list, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ReferenceAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ReferenceAST *_other = pattern->asReference()) {
+        if (! matcher->match(this, _other))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool BreakStatementAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (BreakStatementAST *_other = pattern->asBreakStatement()) {
+        if (! matcher->match(this, _other))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ContinueStatementAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ContinueStatementAST *_other = pattern->asContinueStatement()) {
+        if (! matcher->match(this, _other))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool GotoStatementAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (GotoStatementAST *_other = pattern->asGotoStatement()) {
+        if (! matcher->match(this, _other))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ReturnStatementAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ReturnStatementAST *_other = pattern->asReturnStatement()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(expression, _other->expression, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool SizeofExpressionAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (SizeofExpressionAST *_other = pattern->asSizeofExpression()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(expression, _other->expression, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool NumericLiteralAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (NumericLiteralAST *_other = pattern->asNumericLiteral()) {
+        if (! matcher->match(this, _other))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool BoolLiteralAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (BoolLiteralAST *_other = pattern->asBoolLiteral()) {
+        if (! matcher->match(this, _other))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ThisExpressionAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ThisExpressionAST *_other = pattern->asThisExpression()) {
+        if (! matcher->match(this, _other))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool NestedExpressionAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (NestedExpressionAST *_other = pattern->asNestedExpression()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(expression, _other->expression, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool StringLiteralAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (StringLiteralAST *_other = pattern->asStringLiteral()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(next, _other->next, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool SwitchStatementAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (SwitchStatementAST *_other = pattern->asSwitchStatement()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(condition, _other->condition, matcher))
+            return false;
+        if (! match(statement, _other->statement, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool TemplateDeclarationAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (TemplateDeclarationAST *_other = pattern->asTemplateDeclaration()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(template_parameter_list, _other->template_parameter_list, matcher))
+            return false;
+        if (! match(declaration, _other->declaration, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ThrowExpressionAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ThrowExpressionAST *_other = pattern->asThrowExpression()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(expression, _other->expression, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool TranslationUnitAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (TranslationUnitAST *_other = pattern->asTranslationUnit()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(declaration_list, _other->declaration_list, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool TryBlockStatementAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (TryBlockStatementAST *_other = pattern->asTryBlockStatement()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(statement, _other->statement, matcher))
+            return false;
+        if (! match(catch_clause_list, _other->catch_clause_list, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool CatchClauseAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (CatchClauseAST *_other = pattern->asCatchClause()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(exception_declaration, _other->exception_declaration, matcher))
+            return false;
+        if (! match(statement, _other->statement, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool TypeIdAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (TypeIdAST *_other = pattern->asTypeId()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(type_specifier_list, _other->type_specifier_list, matcher))
+            return false;
+        if (! match(declarator, _other->declarator, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool TypenameTypeParameterAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (TypenameTypeParameterAST *_other = pattern->asTypenameTypeParameter()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(name, _other->name, matcher))
+            return false;
+        if (! match(type_id, _other->type_id, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool TemplateTypeParameterAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (TemplateTypeParameterAST *_other = pattern->asTemplateTypeParameter()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(template_parameter_list, _other->template_parameter_list, matcher))
+            return false;
+        if (! match(name, _other->name, matcher))
+            return false;
+        if (! match(type_id, _other->type_id, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool UnaryExpressionAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (UnaryExpressionAST *_other = pattern->asUnaryExpression()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(expression, _other->expression, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool UsingAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (UsingAST *_other = pattern->asUsing()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(name, _other->name, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool UsingDirectiveAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (UsingDirectiveAST *_other = pattern->asUsingDirective()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(name, _other->name, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool WhileStatementAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (WhileStatementAST *_other = pattern->asWhileStatement()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(condition, _other->condition, matcher))
+            return false;
+        if (! match(statement, _other->statement, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ObjCClassForwardDeclarationAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ObjCClassForwardDeclarationAST *_other = pattern->asObjCClassForwardDeclaration()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(attribute_list, _other->attribute_list, matcher))
+            return false;
+        if (! match(identifier_list, _other->identifier_list, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ObjCClassDeclarationAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ObjCClassDeclarationAST *_other = pattern->asObjCClassDeclaration()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(attribute_list, _other->attribute_list, matcher))
+            return false;
+        if (! match(class_name, _other->class_name, matcher))
+            return false;
+        if (! match(category_name, _other->category_name, matcher))
+            return false;
+        if (! match(superclass, _other->superclass, matcher))
+            return false;
+        if (! match(protocol_refs, _other->protocol_refs, matcher))
+            return false;
+        if (! match(inst_vars_decl, _other->inst_vars_decl, matcher))
+            return false;
+        if (! match(member_declaration_list, _other->member_declaration_list, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ObjCProtocolForwardDeclarationAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ObjCProtocolForwardDeclarationAST *_other = pattern->asObjCProtocolForwardDeclaration()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(attribute_list, _other->attribute_list, matcher))
+            return false;
+        if (! match(identifier_list, _other->identifier_list, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ObjCProtocolDeclarationAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ObjCProtocolDeclarationAST *_other = pattern->asObjCProtocolDeclaration()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(attribute_list, _other->attribute_list, matcher))
+            return false;
+        if (! match(name, _other->name, matcher))
+            return false;
+        if (! match(protocol_refs, _other->protocol_refs, matcher))
+            return false;
+        if (! match(member_declaration_list, _other->member_declaration_list, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ObjCProtocolRefsAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ObjCProtocolRefsAST *_other = pattern->asObjCProtocolRefs()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(identifier_list, _other->identifier_list, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ObjCMessageArgumentAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ObjCMessageArgumentAST *_other = pattern->asObjCMessageArgument()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(parameter_value_expression, _other->parameter_value_expression, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ObjCMessageExpressionAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ObjCMessageExpressionAST *_other = pattern->asObjCMessageExpression()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(receiver_expression, _other->receiver_expression, matcher))
+            return false;
+        if (! match(selector, _other->selector, matcher))
+            return false;
+        if (! match(argument_list, _other->argument_list, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ObjCProtocolExpressionAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ObjCProtocolExpressionAST *_other = pattern->asObjCProtocolExpression()) {
+        if (! matcher->match(this, _other))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ObjCTypeNameAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ObjCTypeNameAST *_other = pattern->asObjCTypeName()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(type_id, _other->type_id, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ObjCEncodeExpressionAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ObjCEncodeExpressionAST *_other = pattern->asObjCEncodeExpression()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(type_name, _other->type_name, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ObjCSelectorWithoutArgumentsAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ObjCSelectorWithoutArgumentsAST *_other = pattern->asObjCSelectorWithoutArguments()) {
+        if (! matcher->match(this, _other))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ObjCSelectorArgumentAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ObjCSelectorArgumentAST *_other = pattern->asObjCSelectorArgument()) {
+        if (! matcher->match(this, _other))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ObjCSelectorWithArgumentsAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ObjCSelectorWithArgumentsAST *_other = pattern->asObjCSelectorWithArguments()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(selector_argument_list, _other->selector_argument_list, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ObjCSelectorExpressionAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ObjCSelectorExpressionAST *_other = pattern->asObjCSelectorExpression()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(selector, _other->selector, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ObjCInstanceVariablesDeclarationAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ObjCInstanceVariablesDeclarationAST *_other = pattern->asObjCInstanceVariablesDeclaration()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(instance_variable_list, _other->instance_variable_list, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ObjCVisibilityDeclarationAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ObjCVisibilityDeclarationAST *_other = pattern->asObjCVisibilityDeclaration()) {
+        if (! matcher->match(this, _other))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ObjCPropertyAttributeAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ObjCPropertyAttributeAST *_other = pattern->asObjCPropertyAttribute()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(method_selector, _other->method_selector, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ObjCPropertyDeclarationAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ObjCPropertyDeclarationAST *_other = pattern->asObjCPropertyDeclaration()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(attribute_list, _other->attribute_list, matcher))
+            return false;
+        if (! match(property_attribute_list, _other->property_attribute_list, matcher))
+            return false;
+        if (! match(simple_declaration, _other->simple_declaration, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ObjCMessageArgumentDeclarationAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ObjCMessageArgumentDeclarationAST *_other = pattern->asObjCMessageArgumentDeclaration()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(type_name, _other->type_name, matcher))
+            return false;
+        if (! match(attribute_list, _other->attribute_list, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ObjCMethodPrototypeAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ObjCMethodPrototypeAST *_other = pattern->asObjCMethodPrototype()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(type_name, _other->type_name, matcher))
+            return false;
+        if (! match(selector, _other->selector, matcher))
+            return false;
+        if (! match(argument_list, _other->argument_list, matcher))
+            return false;
+        if (! match(attribute_list, _other->attribute_list, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ObjCMethodDeclarationAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ObjCMethodDeclarationAST *_other = pattern->asObjCMethodDeclaration()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(method_prototype, _other->method_prototype, matcher))
+            return false;
+        if (! match(function_body, _other->function_body, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ObjCSynthesizedPropertyAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ObjCSynthesizedPropertyAST *_other = pattern->asObjCSynthesizedProperty()) {
+        if (! matcher->match(this, _other))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ObjCSynthesizedPropertiesDeclarationAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ObjCSynthesizedPropertiesDeclarationAST *_other = pattern->asObjCSynthesizedPropertiesDeclaration()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(property_identifier_list, _other->property_identifier_list, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ObjCDynamicPropertiesDeclarationAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ObjCDynamicPropertiesDeclarationAST *_other = pattern->asObjCDynamicPropertiesDeclaration()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(property_identifier_list, _other->property_identifier_list, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ObjCFastEnumerationAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ObjCFastEnumerationAST *_other = pattern->asObjCFastEnumeration()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(type_specifier_list, _other->type_specifier_list, matcher))
+            return false;
+        if (! match(declarator, _other->declarator, matcher))
+            return false;
+        if (! match(initializer, _other->initializer, matcher))
+            return false;
+        if (! match(fast_enumeratable_expression, _other->fast_enumeratable_expression, matcher))
+            return false;
+        if (! match(body_statement, _other->body_statement, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
+bool ObjCSynchronizedStatementAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ObjCSynchronizedStatementAST *_other = pattern->asObjCSynchronizedStatement()) {
+        if (! matcher->match(this, _other))
+            return false;
+        if (! match(synchronized_object, _other->synchronized_object, matcher))
+            return false;
+        if (! match(statement, _other->statement, matcher))
+            return false;
+        return true;
+    }
+    return false;
+}
+
diff --git a/src/shared/cplusplus/ASTMatcher.cpp b/src/shared/cplusplus/ASTMatcher.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f7135c1311c9c7b84f07665e3f1b9d7d5bba1987
--- /dev/null
+++ b/src/shared/cplusplus/ASTMatcher.cpp
@@ -0,0 +1,693 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "ASTMatcher.h"
+#include "Control.h"
+#include "TranslationUnit.h"
+
+using namespace CPlusPlus;
+
+Control *ASTMatcher::control() const
+{ return _control; }
+
+TranslationUnit *ASTMatcher::translationUnit() const
+{ return _control->translationUnit(); }
+
+unsigned ASTMatcher::tokenCount() const
+{ return translationUnit()->tokenCount(); }
+
+const Token &ASTMatcher::tokenAt(unsigned index) const
+{ return translationUnit()->tokenAt(index); }
+
+int ASTMatcher::tokenKind(unsigned index) const
+{ return translationUnit()->tokenKind(index); }
+
+const char *ASTMatcher::spell(unsigned index) const
+{ return translationUnit()->spell(index); }
+
+Identifier *ASTMatcher::identifier(unsigned index) const
+{ return translationUnit()->identifier(index); }
+
+Literal *ASTMatcher::literal(unsigned index) const
+{ return translationUnit()->literal(index); }
+
+NumericLiteral *ASTMatcher::numericLiteral(unsigned index) const
+{ return translationUnit()->numericLiteral(index); }
+
+StringLiteral *ASTMatcher::stringLiteral(unsigned index) const
+{ return translationUnit()->stringLiteral(index); }
+
+void ASTMatcher::getPosition(unsigned offset,
+                             unsigned *line,
+                             unsigned *column,
+                             StringLiteral **fileName) const
+{ translationUnit()->getPosition(offset, line, column, fileName); }
+
+void ASTMatcher::getTokenPosition(unsigned index,
+                                  unsigned *line,
+                                  unsigned *column,
+                                  StringLiteral **fileName) const
+{ translationUnit()->getTokenPosition(index, line, column, fileName); }
+
+void ASTMatcher::getTokenStartPosition(unsigned index, unsigned *line, unsigned *column) const
+{ getPosition(tokenAt(index).begin(), line, column); }
+
+void ASTMatcher::getTokenEndPosition(unsigned index, unsigned *line, unsigned *column) const
+{ getPosition(tokenAt(index).end(), line, column); }
+
+
+bool ASTMatcher::match(AccessDeclarationAST *, AccessDeclarationAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ArrayAccessAST *, ArrayAccessAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ArrayDeclaratorAST *, ArrayDeclaratorAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ArrayInitializerAST *, ArrayInitializerAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(AsmDefinitionAST *, AsmDefinitionAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(AttributeSpecifierAST *, AttributeSpecifierAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(AttributeAST *, AttributeAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(BaseSpecifierAST *, BaseSpecifierAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(BinaryExpressionAST *, BinaryExpressionAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(BoolLiteralAST *, BoolLiteralAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(BreakStatementAST *, BreakStatementAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(CallAST *, CallAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(CaseStatementAST *, CaseStatementAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(CastExpressionAST *, CastExpressionAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(CatchClauseAST *, CatchClauseAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ClassSpecifierAST *, ClassSpecifierAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(CompoundLiteralAST *, CompoundLiteralAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(CompoundStatementAST *, CompoundStatementAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ConditionAST *, ConditionAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ConditionalExpressionAST *, ConditionalExpressionAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ContinueStatementAST *, ContinueStatementAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ConversionFunctionIdAST *, ConversionFunctionIdAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(CppCastExpressionAST *, CppCastExpressionAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(CtorInitializerAST *, CtorInitializerAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(DeclaratorAST *, DeclaratorAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(DeclarationStatementAST *, DeclarationStatementAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(DeclaratorIdAST *, DeclaratorIdAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(DeleteExpressionAST *, DeleteExpressionAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(DestructorNameAST *, DestructorNameAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(DoStatementAST *, DoStatementAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ElaboratedTypeSpecifierAST *, ElaboratedTypeSpecifierAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(EmptyDeclarationAST *, EmptyDeclarationAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(EnumSpecifierAST *, EnumSpecifierAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(EnumeratorAST *, EnumeratorAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ExceptionDeclarationAST *, ExceptionDeclarationAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ExceptionSpecificationAST *, ExceptionSpecificationAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ExpressionOrDeclarationStatementAST *, ExpressionOrDeclarationStatementAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ExpressionStatementAST *, ExpressionStatementAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ForeachStatementAST *, ForeachStatementAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ForStatementAST *, ForStatementAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(FunctionDeclaratorAST *, FunctionDeclaratorAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(FunctionDefinitionAST *, FunctionDefinitionAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(GotoStatementAST *, GotoStatementAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(IfStatementAST *, IfStatementAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(LabeledStatementAST *, LabeledStatementAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(LinkageBodyAST *, LinkageBodyAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(LinkageSpecificationAST *, LinkageSpecificationAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(MemInitializerAST *, MemInitializerAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(MemberAccessAST *, MemberAccessAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(NamedTypeSpecifierAST *, NamedTypeSpecifierAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(NamespaceAST *, NamespaceAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(NamespaceAliasDefinitionAST *, NamespaceAliasDefinitionAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(NestedDeclaratorAST *, NestedDeclaratorAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(NestedExpressionAST *, NestedExpressionAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(NestedNameSpecifierAST *, NestedNameSpecifierAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(NewPlacementAST *, NewPlacementAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(NewArrayDeclaratorAST *, NewArrayDeclaratorAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(NewExpressionAST *, NewExpressionAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(NewInitializerAST *, NewInitializerAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(NewTypeIdAST *, NewTypeIdAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(NumericLiteralAST *, NumericLiteralAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(OperatorAST *, OperatorAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(OperatorFunctionIdAST *, OperatorFunctionIdAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ParameterDeclarationAST *, ParameterDeclarationAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ParameterDeclarationClauseAST *, ParameterDeclarationClauseAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(PointerAST *, PointerAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(PointerToMemberAST *, PointerToMemberAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(PostIncrDecrAST *, PostIncrDecrAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(PostfixExpressionAST *, PostfixExpressionAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(QualifiedNameAST *, QualifiedNameAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ReferenceAST *, ReferenceAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ReturnStatementAST *, ReturnStatementAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(SimpleDeclarationAST *, SimpleDeclarationAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(SimpleNameAST *, SimpleNameAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(SimpleSpecifierAST *, SimpleSpecifierAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(SizeofExpressionAST *, SizeofExpressionAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(StringLiteralAST *, StringLiteralAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(SwitchStatementAST *, SwitchStatementAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(TemplateDeclarationAST *, TemplateDeclarationAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(TemplateIdAST *, TemplateIdAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(TemplateTypeParameterAST *, TemplateTypeParameterAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ThisExpressionAST *, ThisExpressionAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ThrowExpressionAST *, ThrowExpressionAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(TranslationUnitAST *, TranslationUnitAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(TryBlockStatementAST *, TryBlockStatementAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(TypeConstructorCallAST *, TypeConstructorCallAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(TypeIdAST *, TypeIdAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(TypeidExpressionAST *, TypeidExpressionAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(TypeofSpecifierAST *, TypeofSpecifierAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(TypenameCallExpressionAST *, TypenameCallExpressionAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(TypenameTypeParameterAST *, TypenameTypeParameterAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(UnaryExpressionAST *, UnaryExpressionAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(UsingAST *, UsingAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(UsingDirectiveAST *, UsingDirectiveAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(WhileStatementAST *, WhileStatementAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(QtMethodAST *, QtMethodAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ObjCClassDeclarationAST *, ObjCClassDeclarationAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ObjCClassForwardDeclarationAST *, ObjCClassForwardDeclarationAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ObjCProtocolDeclarationAST *, ObjCProtocolDeclarationAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ObjCProtocolForwardDeclarationAST *, ObjCProtocolForwardDeclarationAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ObjCProtocolRefsAST *, ObjCProtocolRefsAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ObjCMessageExpressionAST *, ObjCMessageExpressionAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ObjCMessageArgumentAST *, ObjCMessageArgumentAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ObjCProtocolExpressionAST *, ObjCProtocolExpressionAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ObjCTypeNameAST *, ObjCTypeNameAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ObjCEncodeExpressionAST *, ObjCEncodeExpressionAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ObjCSelectorWithoutArgumentsAST *, ObjCSelectorWithoutArgumentsAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ObjCSelectorArgumentAST *, ObjCSelectorArgumentAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ObjCSelectorWithArgumentsAST *, ObjCSelectorWithArgumentsAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ObjCSelectorExpressionAST *, ObjCSelectorExpressionAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ObjCInstanceVariablesDeclarationAST *, ObjCInstanceVariablesDeclarationAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ObjCVisibilityDeclarationAST *, ObjCVisibilityDeclarationAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ObjCPropertyAttributeAST *, ObjCPropertyAttributeAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ObjCPropertyDeclarationAST *, ObjCPropertyDeclarationAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ObjCMethodPrototypeAST *, ObjCMethodPrototypeAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ObjCMethodDeclarationAST *, ObjCMethodDeclarationAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ObjCMessageArgumentDeclarationAST *, ObjCMessageArgumentDeclarationAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ObjCSynthesizedPropertyAST *, ObjCSynthesizedPropertyAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ObjCSynthesizedPropertiesDeclarationAST *, ObjCSynthesizedPropertiesDeclarationAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ObjCDynamicPropertiesDeclarationAST *, ObjCDynamicPropertiesDeclarationAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ObjCFastEnumerationAST *, ObjCFastEnumerationAST *)
+{
+    return true;
+}
+
+bool ASTMatcher::match(ObjCSynchronizedStatementAST *, ObjCSynchronizedStatementAST *)
+{
+    return true;
+}
diff --git a/src/shared/cplusplus/ASTMatcher.h b/src/shared/cplusplus/ASTMatcher.h
new file mode 100644
index 0000000000000000000000000000000000000000..171f8a56e085fd4da108562b8b74afe198468d87
--- /dev/null
+++ b/src/shared/cplusplus/ASTMatcher.h
@@ -0,0 +1,195 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+#ifndef ASTMATCHER_H
+#define ASTMATCHER_H
+
+#include "ASTfwd.h"
+
+namespace CPlusPlus {
+
+class CPLUSPLUS_EXPORT ASTMatcher
+{
+public:
+    ASTMatcher(Control *control);
+    virtual ~ASTMatcher();
+
+    Control *control() const;
+    TranslationUnit *translationUnit() const;
+
+    unsigned tokenCount() const;
+    const Token &tokenAt(unsigned index) const;
+    int tokenKind(unsigned index) const;
+    const char *spell(unsigned index) const;
+    Identifier *identifier(unsigned index) const;
+    Literal *literal(unsigned index) const;
+    NumericLiteral *numericLiteral(unsigned index) const;
+    StringLiteral *stringLiteral(unsigned index) const;
+
+    void getPosition(unsigned offset,
+                     unsigned *line,
+                     unsigned *column = 0,
+                     StringLiteral **fileName = 0) const;
+
+    void getTokenPosition(unsigned index,
+                          unsigned *line,
+                          unsigned *column = 0,
+                          StringLiteral **fileName = 0) const;
+
+    void getTokenStartPosition(unsigned index, unsigned *line, unsigned *column) const;
+
+    void getTokenEndPosition(unsigned index, unsigned *line, unsigned *column) const;    virtual bool match(AccessDeclarationAST *node, AccessDeclarationAST *pattern);
+    virtual bool match(ArrayAccessAST *node, ArrayAccessAST *pattern);
+    virtual bool match(ArrayDeclaratorAST *node, ArrayDeclaratorAST *pattern);
+    virtual bool match(ArrayInitializerAST *node, ArrayInitializerAST *pattern);
+    virtual bool match(AsmDefinitionAST *node, AsmDefinitionAST *pattern);
+    virtual bool match(AttributeSpecifierAST *node, AttributeSpecifierAST *pattern);
+    virtual bool match(AttributeAST *node, AttributeAST *pattern);
+    virtual bool match(BaseSpecifierAST *node, BaseSpecifierAST *pattern);
+    virtual bool match(BinaryExpressionAST *node, BinaryExpressionAST *pattern);
+    virtual bool match(BoolLiteralAST *node, BoolLiteralAST *pattern);
+    virtual bool match(BreakStatementAST *node, BreakStatementAST *pattern);
+    virtual bool match(CallAST *node, CallAST *pattern);
+    virtual bool match(CaseStatementAST *node, CaseStatementAST *pattern);
+    virtual bool match(CastExpressionAST *node, CastExpressionAST *pattern);
+    virtual bool match(CatchClauseAST *node, CatchClauseAST *pattern);
+    virtual bool match(ClassSpecifierAST *node, ClassSpecifierAST *pattern);
+    virtual bool match(CompoundLiteralAST *node, CompoundLiteralAST *pattern);
+    virtual bool match(CompoundStatementAST *node, CompoundStatementAST *pattern);
+    virtual bool match(ConditionAST *node, ConditionAST *pattern);
+    virtual bool match(ConditionalExpressionAST *node, ConditionalExpressionAST *pattern);
+    virtual bool match(ContinueStatementAST *node, ContinueStatementAST *pattern);
+    virtual bool match(ConversionFunctionIdAST *node, ConversionFunctionIdAST *pattern);
+    virtual bool match(CppCastExpressionAST *node, CppCastExpressionAST *pattern);
+    virtual bool match(CtorInitializerAST *node, CtorInitializerAST *pattern);
+    virtual bool match(DeclaratorAST *node, DeclaratorAST *pattern);
+    virtual bool match(DeclarationStatementAST *node, DeclarationStatementAST *pattern);
+    virtual bool match(DeclaratorIdAST *node, DeclaratorIdAST *pattern);
+    virtual bool match(DeleteExpressionAST *node, DeleteExpressionAST *pattern);
+    virtual bool match(DestructorNameAST *node, DestructorNameAST *pattern);
+    virtual bool match(DoStatementAST *node, DoStatementAST *pattern);
+    virtual bool match(ElaboratedTypeSpecifierAST *node, ElaboratedTypeSpecifierAST *pattern);
+    virtual bool match(EmptyDeclarationAST *node, EmptyDeclarationAST *pattern);
+    virtual bool match(EnumSpecifierAST *node, EnumSpecifierAST *pattern);
+    virtual bool match(EnumeratorAST *node, EnumeratorAST *pattern);
+    virtual bool match(ExceptionDeclarationAST *node, ExceptionDeclarationAST *pattern);
+    virtual bool match(ExceptionSpecificationAST *node, ExceptionSpecificationAST *pattern);
+    virtual bool match(ExpressionOrDeclarationStatementAST *node, ExpressionOrDeclarationStatementAST *pattern);
+    virtual bool match(ExpressionStatementAST *node, ExpressionStatementAST *pattern);
+    virtual bool match(ForeachStatementAST *node, ForeachStatementAST *pattern);
+    virtual bool match(ForStatementAST *node, ForStatementAST *pattern);
+    virtual bool match(FunctionDeclaratorAST *node, FunctionDeclaratorAST *pattern);
+    virtual bool match(FunctionDefinitionAST *node, FunctionDefinitionAST *pattern);
+    virtual bool match(GotoStatementAST *node, GotoStatementAST *pattern);
+    virtual bool match(IfStatementAST *node, IfStatementAST *pattern);
+    virtual bool match(LabeledStatementAST *node, LabeledStatementAST *pattern);
+    virtual bool match(LinkageBodyAST *node, LinkageBodyAST *pattern);
+    virtual bool match(LinkageSpecificationAST *node, LinkageSpecificationAST *pattern);
+    virtual bool match(MemInitializerAST *node, MemInitializerAST *pattern);
+    virtual bool match(MemberAccessAST *node, MemberAccessAST *pattern);
+    virtual bool match(NamedTypeSpecifierAST *node, NamedTypeSpecifierAST *pattern);
+    virtual bool match(NamespaceAST *node, NamespaceAST *pattern);
+    virtual bool match(NamespaceAliasDefinitionAST *node, NamespaceAliasDefinitionAST *pattern);
+    virtual bool match(NestedDeclaratorAST *node, NestedDeclaratorAST *pattern);
+    virtual bool match(NestedExpressionAST *node, NestedExpressionAST *pattern);
+    virtual bool match(NestedNameSpecifierAST *node, NestedNameSpecifierAST *pattern);
+    virtual bool match(NewPlacementAST *node, NewPlacementAST *pattern);
+    virtual bool match(NewArrayDeclaratorAST *node, NewArrayDeclaratorAST *pattern);
+    virtual bool match(NewExpressionAST *node, NewExpressionAST *pattern);
+    virtual bool match(NewInitializerAST *node, NewInitializerAST *pattern);
+    virtual bool match(NewTypeIdAST *node, NewTypeIdAST *pattern);
+    virtual bool match(NumericLiteralAST *node, NumericLiteralAST *pattern);
+    virtual bool match(OperatorAST *node, OperatorAST *pattern);
+    virtual bool match(OperatorFunctionIdAST *node, OperatorFunctionIdAST *pattern);
+    virtual bool match(ParameterDeclarationAST *node, ParameterDeclarationAST *pattern);
+    virtual bool match(ParameterDeclarationClauseAST *node, ParameterDeclarationClauseAST *pattern);
+    virtual bool match(PointerAST *node, PointerAST *pattern);
+    virtual bool match(PointerToMemberAST *node, PointerToMemberAST *pattern);
+    virtual bool match(PostIncrDecrAST *node, PostIncrDecrAST *pattern);
+    virtual bool match(PostfixExpressionAST *node, PostfixExpressionAST *pattern);
+    virtual bool match(QualifiedNameAST *node, QualifiedNameAST *pattern);
+    virtual bool match(ReferenceAST *node, ReferenceAST *pattern);
+    virtual bool match(ReturnStatementAST *node, ReturnStatementAST *pattern);
+    virtual bool match(SimpleDeclarationAST *node, SimpleDeclarationAST *pattern);
+    virtual bool match(SimpleNameAST *node, SimpleNameAST *pattern);
+    virtual bool match(SimpleSpecifierAST *node, SimpleSpecifierAST *pattern);
+    virtual bool match(SizeofExpressionAST *node, SizeofExpressionAST *pattern);
+    virtual bool match(StringLiteralAST *node, StringLiteralAST *pattern);
+    virtual bool match(SwitchStatementAST *node, SwitchStatementAST *pattern);
+    virtual bool match(TemplateDeclarationAST *node, TemplateDeclarationAST *pattern);
+    virtual bool match(TemplateIdAST *node, TemplateIdAST *pattern);
+    virtual bool match(TemplateTypeParameterAST *node, TemplateTypeParameterAST *pattern);
+    virtual bool match(ThisExpressionAST *node, ThisExpressionAST *pattern);
+    virtual bool match(ThrowExpressionAST *node, ThrowExpressionAST *pattern);
+    virtual bool match(TranslationUnitAST *node, TranslationUnitAST *pattern);
+    virtual bool match(TryBlockStatementAST *node, TryBlockStatementAST *pattern);
+    virtual bool match(TypeConstructorCallAST *node, TypeConstructorCallAST *pattern);
+    virtual bool match(TypeIdAST *node, TypeIdAST *pattern);
+    virtual bool match(TypeidExpressionAST *node, TypeidExpressionAST *pattern);
+    virtual bool match(TypeofSpecifierAST *node, TypeofSpecifierAST *pattern);
+    virtual bool match(TypenameCallExpressionAST *node, TypenameCallExpressionAST *pattern);
+    virtual bool match(TypenameTypeParameterAST *node, TypenameTypeParameterAST *pattern);
+    virtual bool match(UnaryExpressionAST *node, UnaryExpressionAST *pattern);
+    virtual bool match(UsingAST *node, UsingAST *pattern);
+    virtual bool match(UsingDirectiveAST *node, UsingDirectiveAST *pattern);
+    virtual bool match(WhileStatementAST *node, WhileStatementAST *pattern);
+    virtual bool match(QtMethodAST *node, QtMethodAST *pattern);
+    virtual bool match(ObjCClassDeclarationAST *node, ObjCClassDeclarationAST *pattern);
+    virtual bool match(ObjCClassForwardDeclarationAST *node, ObjCClassForwardDeclarationAST *pattern);
+    virtual bool match(ObjCProtocolDeclarationAST *node, ObjCProtocolDeclarationAST *pattern);
+    virtual bool match(ObjCProtocolForwardDeclarationAST *node, ObjCProtocolForwardDeclarationAST *pattern);
+    virtual bool match(ObjCProtocolRefsAST *node, ObjCProtocolRefsAST *pattern);
+    virtual bool match(ObjCMessageExpressionAST *node, ObjCMessageExpressionAST *pattern);
+    virtual bool match(ObjCMessageArgumentAST *node, ObjCMessageArgumentAST *pattern);
+    virtual bool match(ObjCProtocolExpressionAST *node, ObjCProtocolExpressionAST *pattern);
+    virtual bool match(ObjCTypeNameAST *node, ObjCTypeNameAST *pattern);
+    virtual bool match(ObjCEncodeExpressionAST *node, ObjCEncodeExpressionAST *pattern);
+    virtual bool match(ObjCSelectorWithoutArgumentsAST *node, ObjCSelectorWithoutArgumentsAST *pattern);
+    virtual bool match(ObjCSelectorArgumentAST *node, ObjCSelectorArgumentAST *pattern);
+    virtual bool match(ObjCSelectorWithArgumentsAST *node, ObjCSelectorWithArgumentsAST *pattern);
+    virtual bool match(ObjCSelectorExpressionAST *node, ObjCSelectorExpressionAST *pattern);
+    virtual bool match(ObjCInstanceVariablesDeclarationAST *node, ObjCInstanceVariablesDeclarationAST *pattern);
+    virtual bool match(ObjCVisibilityDeclarationAST *node, ObjCVisibilityDeclarationAST *pattern);
+    virtual bool match(ObjCPropertyAttributeAST *node, ObjCPropertyAttributeAST *pattern);
+    virtual bool match(ObjCPropertyDeclarationAST *node, ObjCPropertyDeclarationAST *pattern);
+    virtual bool match(ObjCMethodPrototypeAST *node, ObjCMethodPrototypeAST *pattern);
+    virtual bool match(ObjCMethodDeclarationAST *node, ObjCMethodDeclarationAST *pattern);
+    virtual bool match(ObjCMessageArgumentDeclarationAST *node, ObjCMessageArgumentDeclarationAST *pattern);
+    virtual bool match(ObjCSynthesizedPropertyAST *node, ObjCSynthesizedPropertyAST *pattern);
+    virtual bool match(ObjCSynthesizedPropertiesDeclarationAST *node, ObjCSynthesizedPropertiesDeclarationAST *pattern);
+    virtual bool match(ObjCDynamicPropertiesDeclarationAST *node, ObjCDynamicPropertiesDeclarationAST *pattern);
+    virtual bool match(ObjCFastEnumerationAST *node, ObjCFastEnumerationAST *pattern);
+    virtual bool match(ObjCSynchronizedStatementAST *node, ObjCSynchronizedStatementAST *pattern);
+
+private:
+    Control *_control;
+};
+
+} // end of namespace CPlusPlus
+
+#endif // ASTMATCHER_H
diff --git a/src/shared/cplusplus/ASTfwd.h b/src/shared/cplusplus/ASTfwd.h
index aaeeed94aed89e50fbf55eb309a826778449e1c1..18f1987d5e99b6a5024bc887cbaa2a83f4545fe1 100644
--- a/src/shared/cplusplus/ASTfwd.h
+++ b/src/shared/cplusplus/ASTfwd.h
@@ -57,6 +57,7 @@ template <typename _Tp> class List;
 
 class AST;
 class ASTVisitor;
+class ASTMatcher;
 
 class AccessDeclarationAST;
 class ArrayAccessAST;
diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp
index 89694bab592baf71ebf21acc3e8837d7f504402e..36b7d03e1cf168295b113c7f54de799f252548df 100644
--- a/src/shared/cplusplus/Parser.cpp
+++ b/src/shared/cplusplus/Parser.cpp
@@ -2419,7 +2419,7 @@ bool Parser::parseForStatement(StatementAST *&node)
     ast->for_token = for_token;
     ast->lparen_token = lparen_token;
     parseForInitStatement(ast->initializer);
-    parseExpression(ast->condition);
+    parseCondition(ast->condition);
     match(T_SEMICOLON, &ast->semicolon_token);
     parseExpression(ast->expression);
     match(T_RPAREN, &ast->rparen_token);
diff --git a/src/shared/cplusplus/cplusplus.pri b/src/shared/cplusplus/cplusplus.pri
index ddb82afbcd0bb2038cea1cb36c0d8bc145e4fb60..8977a6fa4470ab908ee3c0e297d5be6af6e81a30 100644
--- a/src/shared/cplusplus/cplusplus.pri
+++ b/src/shared/cplusplus/cplusplus.pri
@@ -5,6 +5,7 @@ INCLUDEPATH += $$PWD
 HEADERS += \
     $$PWD/AST.h \
     $$PWD/ASTVisitor.h \
+    $$PWD/ASTMatcher.h \
     $$PWD/ASTfwd.h \
     $$PWD/Array.h \
     $$PWD/CPlusPlusForwardDeclarations.h \
@@ -41,7 +42,9 @@ HEADERS += \
 SOURCES += \
     $$PWD/AST.cpp \
     $$PWD/ASTVisit.cpp \
+    $$PWD/ASTMatch0.cpp \
     $$PWD/ASTVisitor.cpp \
+    $$PWD/ASTMatcher.cpp \
     $$PWD/Array.cpp \
     $$PWD/CheckDeclaration.cpp \
     $$PWD/CheckDeclarator.cpp \
diff --git a/src/tools/cplusplus/Main.cpp b/src/tools/cplusplus/Main.cpp
index 16c9908a13dc020848b2a197c1daa8047f784864..00fc4eea00a19470590774517097d67f3e68a869 100644
--- a/src/tools/cplusplus/Main.cpp
+++ b/src/tools/cplusplus/Main.cpp
@@ -55,66 +55,158 @@ static const char copyrightHeader[] =
 "**************************************************************************/\n"
 ;
 
-class SearchListNodes: protected ASTVisitor
+class VisitCG: protected ASTVisitor
 {
-    QList<QByteArray> _listNodes;
+    QDir _cplusplusDir;
+    QTextStream *out;
 
 public:
-    SearchListNodes(Control *control)
-        : ASTVisitor(control)
+    VisitCG(const QDir &cplusplusDir, Control *control)
+        : ASTVisitor(control), _cplusplusDir(cplusplusDir), out(0)
     { }
 
-    QList<QByteArray> operator()(AST *ast)
+    void operator()(AST *ast)
     {
-        _listNodes.clear();
+        QFileInfo fileInfo(_cplusplusDir, QLatin1String("ASTVisit.cpp"));
+
+        QFile file(fileInfo.absoluteFilePath());
+        if (! file.open(QFile::WriteOnly))
+            return;
+
+        QTextStream output(&file);
+        out = &output;
+
+        *out << copyrightHeader <<
+            "\n"
+            "#include \"AST.h\"\n"
+            "#include \"ASTVisitor.h\"\n"
+            "\n"
+            "using namespace CPlusPlus;\n" << endl;
+
         accept(ast);
-        return _listNodes;
     }
 
 protected:
-    virtual bool visit(ClassSpecifierAST *ast)
+    using ASTVisitor::visit;
+
+    QMap<QByteArray, ClassSpecifierAST *> classMap;
+
+    QByteArray id_cast(NameAST *name)
     {
-        const QString className = oo(ast->symbol->name());
-        
-        if (! (className.length() > 3 && className.endsWith(QLatin1String("AST"))))
-            return true;
+        if (! name)
+            return QByteArray();
+
+        Identifier *id = identifier(name->asSimpleName()->identifier_token);
+
+        return QByteArray::fromRawData(id->chars(), id->size());
+    }
 
-        for (unsigned i = 0; i < ast->symbol->memberCount(); ++i) {
-            Symbol *member = ast->symbol->memberAt(i);
-            Name *memberName = member->name();
+    void visitMembers(Class *klass)
+    {
+        const QByteArray className = klass->name()->identifier()->chars();
 
-            if (! memberName)
+        // *out << "        // visit " << className.constData() << endl;
+        for (unsigned i = 0; i < klass->memberCount(); ++i) {
+            Symbol *member = klass->memberAt(i);
+            if (! member->name())
                 continue;
-            else if (! memberName->identifier())
+
+            Identifier *id = member->name()->identifier();
+
+            if (! id)
                 continue;
-            
-            if (! qstrcmp("next", memberName->identifier()->chars())) {
-                _listNodes.append(className.toUtf8());
-                break;
+
+            const QByteArray memberName = QByteArray::fromRawData(id->chars(), id->size());
+            if (member->type().isUnsigned() && memberName.endsWith("_token")) {
+                // nothing to do. The member is a token.
+
+            } else if (PointerType *ptrTy = member->type()->asPointerType()) {
+
+                if (NamedType *namedTy = ptrTy->elementType()->asNamedType()) {
+                    QByteArray typeName = namedTy->name()->identifier()->chars();
+
+                    if (typeName.endsWith("AST") && memberName != "next") {
+                        *out << "        accept(" << memberName.constData() << ", visitor);" << endl;
+                    }
+                }
+            }
+        }
+
+        for (unsigned i = 0; i < klass->baseClassCount(); ++i) {
+            const QByteArray baseClassName = klass->baseClassAt(i)->identifier()->chars();
+
+            if (ClassSpecifierAST *baseClassSpec = classMap.value(baseClassName, 0)) {
+                visitMembers(baseClassSpec->symbol);
             }
         }
+    }
+
+    bool checkMethod(Symbol *accept0Method) const
+    {
+        Declaration *decl = accept0Method->asDeclaration();
+        if (! decl)
+            return false;
+
+        Function *funTy = decl->type()->asFunctionType();
+        if (! funTy)
+            return false;
+
+        else if (funTy->isPureVirtual())
+            return false;
 
         return true;
     }
 
-private:
-    Overview oo;
+    virtual bool visit(ClassSpecifierAST *ast)
+    {
+        Class *klass = ast->symbol;
+        const QByteArray className = id_cast(ast->name);
+
+        Identifier *visit_id = control()->findOrInsertIdentifier("accept0");
+        Symbol *accept0Method = klass->members()->lookat(visit_id);
+        for (; accept0Method; accept0Method = accept0Method->next()) {
+            if (accept0Method->identifier() != visit_id)
+                continue;
+
+            if (checkMethod(accept0Method))
+                break;
+        }
+
+        if (! accept0Method)
+            return true;
+
+        classMap.insert(className, ast);
+
+        *out
+                << "void " << className.constData() << "::accept0(ASTVisitor *visitor)" << endl
+                << "{" << endl
+                << "    if (visitor->visit(this)) {" << endl;
+
+        visitMembers(klass);
+
+        *out
+                << "    }" << endl
+                << "    visitor->endVisit(this);" << endl
+                << "}" << endl
+                << endl;
+
+        return true;
+    }
 };
 
-class VisitCG: protected ASTVisitor
+class MatchCG: protected ASTVisitor
 {
     QDir _cplusplusDir;
-    QList<QByteArray> _listNodes;
     QTextStream *out;
 
 public:
-    VisitCG(const QDir &cplusplusDir, Control *control)
+    MatchCG(const QDir &cplusplusDir, Control *control)
         : ASTVisitor(control), _cplusplusDir(cplusplusDir), out(0)
     { }
 
     void operator()(AST *ast)
     {
-        QFileInfo fileInfo(_cplusplusDir, QLatin1String("ASTVisit.cpp"));
+        QFileInfo fileInfo(_cplusplusDir, QLatin1String("ASTMatch0.cpp"));
 
         QFile file(fileInfo.absoluteFilePath());
         if (! file.open(QFile::WriteOnly))
@@ -126,13 +218,10 @@ public:
         *out << copyrightHeader <<
             "\n"
             "#include \"AST.h\"\n"
-            "#include \"ASTVisitor.h\"\n"
+            "#include \"ASTMatcher.h\"\n"
             "\n"
             "using namespace CPlusPlus;\n" << endl;
 
-        SearchListNodes listNodes(control());
-        _listNodes = listNodes(ast);
-
         accept(ast);
     }
 
@@ -153,9 +242,14 @@ protected:
 
     void visitMembers(Class *klass)
     {
-        const QByteArray className = klass->name()->identifier()->chars();
+        Overview oo;
+        const QString className = oo(klass->name());
+
+        *out << "    if (" << className << " *_other = pattern->as" << className.left(className.length() - 3) << "()) {" << endl;
+
+        *out << "        if (! matcher->match(this, _other))" << endl
+                << "            return false;" << endl;
 
-        // *out << "        // visit " << className.constData() << endl;
         for (unsigned i = 0; i < klass->memberCount(); ++i) {
             Symbol *member = klass->memberAt(i);
             if (! member->name())
@@ -168,21 +262,17 @@ protected:
 
             const QByteArray memberName = QByteArray::fromRawData(id->chars(), id->size());
             if (member->type().isUnsigned() && memberName.endsWith("_token")) {
-                // nothing to do. The member is a token.
+                // nothing to do here.
 
             } else if (PointerType *ptrTy = member->type()->asPointerType()) {
 
                 if (NamedType *namedTy = ptrTy->elementType()->asNamedType()) {
                     QByteArray typeName = namedTy->name()->identifier()->chars();
 
-                    if (_listNodes.contains(typeName) && memberName != "next") {
-                        *out
-                                << "        for (" << typeName.constData() << " *it = "
-                                << memberName.constData() << "; it; it = it->next)" << endl
-                                << "            accept(it, visitor);" << endl;
+                    if (typeName.endsWith("AST")) {
+                        *out << "        if (! match(" << memberName << ", _other->" << memberName << ", matcher))" << endl
+                                << "            return false;" << endl;
 
-                    } else if (typeName.endsWith("AST") && memberName != "next") {
-                        *out << "        accept(" << memberName.constData() << ", visitor);" << endl;
                     }
                 }
             }
@@ -195,6 +285,9 @@ protected:
                 visitMembers(baseClassSpec->symbol);
             }
         }
+
+        *out << "        return true;" << endl;
+        *out << "    }" << endl;
     }
 
     bool checkMethod(Symbol *accept0Method) const
@@ -218,10 +311,10 @@ protected:
         Class *klass = ast->symbol;
         const QByteArray className = id_cast(ast->name);
 
-        Identifier *visit_id = control()->findOrInsertIdentifier("accept0");
-        Symbol *accept0Method = klass->members()->lookat(visit_id);
+        Identifier *match0_id = control()->findOrInsertIdentifier("match0");
+        Symbol *accept0Method = klass->members()->lookat(match0_id);
         for (; accept0Method; accept0Method = accept0Method->next()) {
-            if (accept0Method->identifier() != visit_id)
+            if (accept0Method->identifier() != match0_id)
                 continue;
 
             if (checkMethod(accept0Method))
@@ -234,15 +327,13 @@ protected:
         classMap.insert(className, ast);
 
         *out
-                << "void " << className.constData() << "::accept0(ASTVisitor *visitor)" << endl
-                << "{" << endl
-                << "    if (visitor->visit(this)) {" << endl;
+                << "bool " << className.constData() << "::match0(AST *pattern, ASTMatcher *matcher)" << endl
+                << "{" << endl;
 
         visitMembers(klass);
 
         *out
-                << "    }" << endl
-                << "    visitor->endVisit(this);" << endl
+                << "    return false;" << endl
                 << "}" << endl
                 << endl;
 
@@ -317,8 +408,8 @@ protected:
                 _nodes.deriveds.append(ast);
 
                 AccessDeclarationAST *accessDeclaration = 0;
-                for (DeclarationListAST *it = ast->member_specifiers; it; it = it->next) {
-                    if (AccessDeclarationAST *decl = it->declaration->asAccessDeclaration()) {
+                for (DeclarationListAST *it = ast->member_specifier_list; it; it = it->next) {
+                    if (AccessDeclarationAST *decl = it->value->asAccessDeclaration()) {
                         if (tokenKind(decl->access_specifier_token) == T_PUBLIC)
                             accessDeclaration = decl;
                     }
@@ -457,6 +548,9 @@ QStringList generateAST_H(const Snapshot &snapshot, const QDir &cplusplusDir)
     VisitCG cg(cplusplusDir, doc->control());
     cg(doc->translationUnit()->ast());
 
+    MatchCG cg2(cplusplusDir, doc->control());
+    cg2(doc->translationUnit()->ast());
+
     return astDerivedClasses;
 }
 
@@ -476,8 +570,11 @@ public:
 protected:
     bool visit(SimpleDeclarationAST *ast)
     {
-        if (ElaboratedTypeSpecifierAST *e = ast->decl_specifier_seq->asElaboratedTypeSpecifier()) {
-            if (tokenKind(e->classkey_token) == T_CLASS && !ast->declarators) {
+        if (! ast->decl_specifier_list)
+            return false;
+
+        if (ElaboratedTypeSpecifierAST *e = ast->decl_specifier_list->value->asElaboratedTypeSpecifier()) {
+            if (tokenKind(e->classkey_token) == T_CLASS && !ast->declarator_list) {
                 QString className = oo(e->name->name);
 
                 if (className.length() > 3 && className.endsWith(QLatin1String("AST"))) {