From ecf712e6bc51dd65a0a414d1fa044aba19ab26cf Mon Sep 17 00:00:00 2001
From: Roberto Raggi <roberto.raggi@nokia.com>
Date: Fri, 13 Nov 2009 11:35:19 +0100
Subject: [PATCH] New matchers

---
 src/shared/cplusplus/ASTMatch0.cpp  | 1350 ++++++++-------------------
 src/shared/cplusplus/ASTMatcher.cpp | 1130 +++++++++++++++++++---
 src/tools/cplusplus/Main.cpp        |  154 ++-
 3 files changed, 1505 insertions(+), 1129 deletions(-)

diff --git a/src/shared/cplusplus/ASTMatch0.cpp b/src/shared/cplusplus/ASTMatch0.cpp
index a6522b5407f..7c4ff19ae6e 100644
--- a/src/shared/cplusplus/ASTMatch0.cpp
+++ b/src/shared/cplusplus/ASTMatch0.cpp
@@ -34,1595 +34,977 @@ using namespace CPlusPlus;
 
 bool SimpleSpecifierAST::match0(AST *pattern, ASTMatcher *matcher)
 {
-    if (SimpleSpecifierAST *_other = pattern->asSimpleSpecifier()) {
-        if (! matcher->match(this, _other))
-            return false;
-        return true;
-    }
+    if (SimpleSpecifierAST *_other = pattern->asSimpleSpecifier())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (AttributeSpecifierAST *_other = pattern->asAttributeSpecifier())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (AttributeAST *_other = pattern->asAttribute())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (TypeofSpecifierAST *_other = pattern->asTypeofSpecifier())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (DeclaratorAST *_other = pattern->asDeclarator())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (SimpleDeclarationAST *_other = pattern->asSimpleDeclaration())
+        return matcher->match(this, _other);
+
     return false;
 }
 
 bool EmptyDeclarationAST::match0(AST *pattern, ASTMatcher *matcher)
 {
-    if (EmptyDeclarationAST *_other = pattern->asEmptyDeclaration()) {
-        if (! matcher->match(this, _other))
-            return false;
-        return true;
-    }
+    if (EmptyDeclarationAST *_other = pattern->asEmptyDeclaration())
+        return matcher->match(this, _other);
+
     return false;
 }
 
 bool AccessDeclarationAST::match0(AST *pattern, ASTMatcher *matcher)
 {
-    if (AccessDeclarationAST *_other = pattern->asAccessDeclaration()) {
-        if (! matcher->match(this, _other))
-            return false;
-        return true;
-    }
+    if (AccessDeclarationAST *_other = pattern->asAccessDeclaration())
+        return matcher->match(this, _other);
+
     return false;
 }
 
 bool AsmDefinitionAST::match0(AST *pattern, ASTMatcher *matcher)
 {
-    if (AsmDefinitionAST *_other = pattern->asAsmDefinition()) {
-        if (! matcher->match(this, _other))
-            return false;
-        return true;
-    }
+    if (AsmDefinitionAST *_other = pattern->asAsmDefinition())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (BaseSpecifierAST *_other = pattern->asBaseSpecifier())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (CompoundLiteralAST *_other = pattern->asCompoundLiteral())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (QtMethodAST *_other = pattern->asQtMethod())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (BinaryExpressionAST *_other = pattern->asBinaryExpression())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (CastExpressionAST *_other = pattern->asCastExpression())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (ClassSpecifierAST *_other = pattern->asClassSpecifier())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (CaseStatementAST *_other = pattern->asCaseStatement())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (CompoundStatementAST *_other = pattern->asCompoundStatement())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (ConditionAST *_other = pattern->asCondition())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (ConditionalExpressionAST *_other = pattern->asConditionalExpression())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (CppCastExpressionAST *_other = pattern->asCppCastExpression())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (CtorInitializerAST *_other = pattern->asCtorInitializer())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (DeclarationStatementAST *_other = pattern->asDeclarationStatement())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (DeclaratorIdAST *_other = pattern->asDeclaratorId())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (NestedDeclaratorAST *_other = pattern->asNestedDeclarator())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (FunctionDeclaratorAST *_other = pattern->asFunctionDeclarator())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (ArrayDeclaratorAST *_other = pattern->asArrayDeclarator())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (DeleteExpressionAST *_other = pattern->asDeleteExpression())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (DoStatementAST *_other = pattern->asDoStatement())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (NamedTypeSpecifierAST *_other = pattern->asNamedTypeSpecifier())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (ElaboratedTypeSpecifierAST *_other = pattern->asElaboratedTypeSpecifier())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (EnumSpecifierAST *_other = pattern->asEnumSpecifier())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (EnumeratorAST *_other = pattern->asEnumerator())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (ExceptionDeclarationAST *_other = pattern->asExceptionDeclaration())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (ExceptionSpecificationAST *_other = pattern->asExceptionSpecification())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (ExpressionOrDeclarationStatementAST *_other = pattern->asExpressionOrDeclarationStatement())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (ExpressionStatementAST *_other = pattern->asExpressionStatement())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (FunctionDefinitionAST *_other = pattern->asFunctionDefinition())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (ForeachStatementAST *_other = pattern->asForeachStatement())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (ForStatementAST *_other = pattern->asForStatement())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (IfStatementAST *_other = pattern->asIfStatement())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (ArrayInitializerAST *_other = pattern->asArrayInitializer())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (LabeledStatementAST *_other = pattern->asLabeledStatement())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (LinkageBodyAST *_other = pattern->asLinkageBody())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (LinkageSpecificationAST *_other = pattern->asLinkageSpecification())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (MemInitializerAST *_other = pattern->asMemInitializer())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (NestedNameSpecifierAST *_other = pattern->asNestedNameSpecifier())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (QualifiedNameAST *_other = pattern->asQualifiedName())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (OperatorFunctionIdAST *_other = pattern->asOperatorFunctionId())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (ConversionFunctionIdAST *_other = pattern->asConversionFunctionId())
+        return matcher->match(this, _other);
+
     return false;
 }
 
 bool SimpleNameAST::match0(AST *pattern, ASTMatcher *matcher)
 {
-    if (SimpleNameAST *_other = pattern->asSimpleName()) {
-        if (! matcher->match(this, _other))
-            return false;
-        return true;
-    }
+    if (SimpleNameAST *_other = pattern->asSimpleName())
+        return matcher->match(this, _other);
+
     return false;
 }
 
 bool DestructorNameAST::match0(AST *pattern, ASTMatcher *matcher)
 {
-    if (DestructorNameAST *_other = pattern->asDestructorName()) {
-        if (! matcher->match(this, _other))
-            return false;
-        return true;
-    }
+    if (DestructorNameAST *_other = pattern->asDestructorName())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (TemplateIdAST *_other = pattern->asTemplateId())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (NamespaceAST *_other = pattern->asNamespace())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (NamespaceAliasDefinitionAST *_other = pattern->asNamespaceAliasDefinition())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (NewPlacementAST *_other = pattern->asNewPlacement())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (NewArrayDeclaratorAST *_other = pattern->asNewArrayDeclarator())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (NewExpressionAST *_other = pattern->asNewExpression())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (NewInitializerAST *_other = pattern->asNewInitializer())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (NewTypeIdAST *_other = pattern->asNewTypeId())
+        return matcher->match(this, _other);
+
     return false;
 }
 
 bool OperatorAST::match0(AST *pattern, ASTMatcher *matcher)
 {
-    if (OperatorAST *_other = pattern->asOperator()) {
-        if (! matcher->match(this, _other))
-            return false;
-        return true;
-    }
+    if (OperatorAST *_other = pattern->asOperator())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (ParameterDeclarationAST *_other = pattern->asParameterDeclaration())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (ParameterDeclarationClauseAST *_other = pattern->asParameterDeclarationClause())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (CallAST *_other = pattern->asCall())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (ArrayAccessAST *_other = pattern->asArrayAccess())
+        return matcher->match(this, _other);
+
     return false;
 }
 
 bool PostIncrDecrAST::match0(AST *pattern, ASTMatcher *matcher)
 {
-    if (PostIncrDecrAST *_other = pattern->asPostIncrDecr()) {
-        if (! matcher->match(this, _other))
-            return false;
-        return true;
-    }
+    if (PostIncrDecrAST *_other = pattern->asPostIncrDecr())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (MemberAccessAST *_other = pattern->asMemberAccess())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (TypeidExpressionAST *_other = pattern->asTypeidExpression())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (TypenameCallExpressionAST *_other = pattern->asTypenameCallExpression())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (TypeConstructorCallAST *_other = pattern->asTypeConstructorCall())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (PostfixExpressionAST *_other = pattern->asPostfixExpression())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (PointerToMemberAST *_other = pattern->asPointerToMember())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (PointerAST *_other = pattern->asPointer())
+        return matcher->match(this, _other);
+
     return false;
 }
 
 bool ReferenceAST::match0(AST *pattern, ASTMatcher *matcher)
 {
-    if (ReferenceAST *_other = pattern->asReference()) {
-        if (! matcher->match(this, _other))
-            return false;
-        return true;
-    }
+    if (ReferenceAST *_other = pattern->asReference())
+        return matcher->match(this, _other);
+
     return false;
 }
 
 bool BreakStatementAST::match0(AST *pattern, ASTMatcher *matcher)
 {
-    if (BreakStatementAST *_other = pattern->asBreakStatement()) {
-        if (! matcher->match(this, _other))
-            return false;
-        return true;
-    }
+    if (BreakStatementAST *_other = pattern->asBreakStatement())
+        return matcher->match(this, _other);
+
     return false;
 }
 
 bool ContinueStatementAST::match0(AST *pattern, ASTMatcher *matcher)
 {
-    if (ContinueStatementAST *_other = pattern->asContinueStatement()) {
-        if (! matcher->match(this, _other))
-            return false;
-        return true;
-    }
+    if (ContinueStatementAST *_other = pattern->asContinueStatement())
+        return matcher->match(this, _other);
+
     return false;
 }
 
 bool GotoStatementAST::match0(AST *pattern, ASTMatcher *matcher)
 {
-    if (GotoStatementAST *_other = pattern->asGotoStatement()) {
-        if (! matcher->match(this, _other))
-            return false;
-        return true;
-    }
+    if (GotoStatementAST *_other = pattern->asGotoStatement())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (ReturnStatementAST *_other = pattern->asReturnStatement())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (SizeofExpressionAST *_other = pattern->asSizeofExpression())
+        return matcher->match(this, _other);
+
     return false;
 }
 
 bool NumericLiteralAST::match0(AST *pattern, ASTMatcher *matcher)
 {
-    if (NumericLiteralAST *_other = pattern->asNumericLiteral()) {
-        if (! matcher->match(this, _other))
-            return false;
-        return true;
-    }
+    if (NumericLiteralAST *_other = pattern->asNumericLiteral())
+        return matcher->match(this, _other);
+
     return false;
 }
 
 bool BoolLiteralAST::match0(AST *pattern, ASTMatcher *matcher)
 {
-    if (BoolLiteralAST *_other = pattern->asBoolLiteral()) {
-        if (! matcher->match(this, _other))
-            return false;
-        return true;
-    }
+    if (BoolLiteralAST *_other = pattern->asBoolLiteral())
+        return matcher->match(this, _other);
+
     return false;
 }
 
 bool ThisExpressionAST::match0(AST *pattern, ASTMatcher *matcher)
 {
-    if (ThisExpressionAST *_other = pattern->asThisExpression()) {
-        if (! matcher->match(this, _other))
-            return false;
-        return true;
-    }
+    if (ThisExpressionAST *_other = pattern->asThisExpression())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (NestedExpressionAST *_other = pattern->asNestedExpression())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (StringLiteralAST *_other = pattern->asStringLiteral())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (SwitchStatementAST *_other = pattern->asSwitchStatement())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (TemplateDeclarationAST *_other = pattern->asTemplateDeclaration())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (ThrowExpressionAST *_other = pattern->asThrowExpression())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (TranslationUnitAST *_other = pattern->asTranslationUnit())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (TryBlockStatementAST *_other = pattern->asTryBlockStatement())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (CatchClauseAST *_other = pattern->asCatchClause())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (TypeIdAST *_other = pattern->asTypeId())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (TypenameTypeParameterAST *_other = pattern->asTypenameTypeParameter())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (TemplateTypeParameterAST *_other = pattern->asTemplateTypeParameter())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (UnaryExpressionAST *_other = pattern->asUnaryExpression())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (UsingAST *_other = pattern->asUsing())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (UsingDirectiveAST *_other = pattern->asUsingDirective())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (WhileStatementAST *_other = pattern->asWhileStatement())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (ObjCClassForwardDeclarationAST *_other = pattern->asObjCClassForwardDeclaration())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (ObjCClassDeclarationAST *_other = pattern->asObjCClassDeclaration())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (ObjCProtocolForwardDeclarationAST *_other = pattern->asObjCProtocolForwardDeclaration())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (ObjCProtocolDeclarationAST *_other = pattern->asObjCProtocolDeclaration())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (ObjCProtocolRefsAST *_other = pattern->asObjCProtocolRefs())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (ObjCMessageArgumentAST *_other = pattern->asObjCMessageArgument())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (ObjCMessageExpressionAST *_other = pattern->asObjCMessageExpression())
+        return matcher->match(this, _other);
+
     return false;
 }
 
 bool ObjCProtocolExpressionAST::match0(AST *pattern, ASTMatcher *matcher)
 {
-    if (ObjCProtocolExpressionAST *_other = pattern->asObjCProtocolExpression()) {
-        if (! matcher->match(this, _other))
-            return false;
-        return true;
-    }
+    if (ObjCProtocolExpressionAST *_other = pattern->asObjCProtocolExpression())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (ObjCTypeNameAST *_other = pattern->asObjCTypeName())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (ObjCEncodeExpressionAST *_other = pattern->asObjCEncodeExpression())
+        return matcher->match(this, _other);
+
     return false;
 }
 
 bool ObjCSelectorWithoutArgumentsAST::match0(AST *pattern, ASTMatcher *matcher)
 {
-    if (ObjCSelectorWithoutArgumentsAST *_other = pattern->asObjCSelectorWithoutArguments()) {
-        if (! matcher->match(this, _other))
-            return false;
-        return true;
-    }
+    if (ObjCSelectorWithoutArgumentsAST *_other = pattern->asObjCSelectorWithoutArguments())
+        return matcher->match(this, _other);
+
     return false;
 }
 
 bool ObjCSelectorArgumentAST::match0(AST *pattern, ASTMatcher *matcher)
 {
-    if (ObjCSelectorArgumentAST *_other = pattern->asObjCSelectorArgument()) {
-        if (! matcher->match(this, _other))
-            return false;
-        return true;
-    }
+    if (ObjCSelectorArgumentAST *_other = pattern->asObjCSelectorArgument())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (ObjCSelectorWithArgumentsAST *_other = pattern->asObjCSelectorWithArguments())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (ObjCSelectorExpressionAST *_other = pattern->asObjCSelectorExpression())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (ObjCInstanceVariablesDeclarationAST *_other = pattern->asObjCInstanceVariablesDeclaration())
+        return matcher->match(this, _other);
+
     return false;
 }
 
 bool ObjCVisibilityDeclarationAST::match0(AST *pattern, ASTMatcher *matcher)
 {
-    if (ObjCVisibilityDeclarationAST *_other = pattern->asObjCVisibilityDeclaration()) {
-        if (! matcher->match(this, _other))
-            return false;
-        return true;
-    }
+    if (ObjCVisibilityDeclarationAST *_other = pattern->asObjCVisibilityDeclaration())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (ObjCPropertyAttributeAST *_other = pattern->asObjCPropertyAttribute())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (ObjCPropertyDeclarationAST *_other = pattern->asObjCPropertyDeclaration())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (ObjCMessageArgumentDeclarationAST *_other = pattern->asObjCMessageArgumentDeclaration())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (ObjCMethodPrototypeAST *_other = pattern->asObjCMethodPrototype())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (ObjCMethodDeclarationAST *_other = pattern->asObjCMethodDeclaration())
+        return matcher->match(this, _other);
+
     return false;
 }
 
 bool ObjCSynthesizedPropertyAST::match0(AST *pattern, ASTMatcher *matcher)
 {
-    if (ObjCSynthesizedPropertyAST *_other = pattern->asObjCSynthesizedProperty()) {
-        if (! matcher->match(this, _other))
-            return false;
-        return true;
-    }
+    if (ObjCSynthesizedPropertyAST *_other = pattern->asObjCSynthesizedProperty())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (ObjCSynthesizedPropertiesDeclarationAST *_other = pattern->asObjCSynthesizedPropertiesDeclaration())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (ObjCDynamicPropertiesDeclarationAST *_other = pattern->asObjCDynamicPropertiesDeclaration())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (ObjCFastEnumerationAST *_other = pattern->asObjCFastEnumeration())
+        return matcher->match(this, _other);
+
     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;
-    }
+    if (ObjCSynchronizedStatementAST *_other = pattern->asObjCSynchronizedStatement())
+        return matcher->match(this, _other);
+
     return false;
 }
 
diff --git a/src/shared/cplusplus/ASTMatcher.cpp b/src/shared/cplusplus/ASTMatcher.cpp
index f7135c1311c..75993309d7d 100644
--- a/src/shared/cplusplus/ASTMatcher.cpp
+++ b/src/shared/cplusplus/ASTMatcher.cpp
@@ -27,12 +27,20 @@
 **
 **************************************************************************/
 
+#include "AST.h"
 #include "ASTMatcher.h"
 #include "Control.h"
 #include "TranslationUnit.h"
 
 using namespace CPlusPlus;
 
+ASTMatcher::ASTMatcher(Control *control)
+    : _control(control)
+{ }
+
+ASTMatcher::~ASTMatcher()
+{ }
+
 Control *ASTMatcher::control() const
 { return _control; }
 
@@ -82,612 +90,1490 @@ void ASTMatcher::getTokenEndPosition(unsigned index, unsigned *line, unsigned *c
 { getPosition(tokenAt(index).end(), line, column); }
 
 
-bool ASTMatcher::match(AccessDeclarationAST *, AccessDeclarationAST *)
+
+bool ASTMatcher::match(SimpleSpecifierAST *node, SimpleSpecifierAST *pattern)
 {
+    if (node->specifier_token != pattern->specifier_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ArrayAccessAST *, ArrayAccessAST *)
+bool ASTMatcher::match(AttributeSpecifierAST *node, AttributeSpecifierAST *pattern)
 {
+    if (node->attribute_token != pattern->attribute_token)
+        return false;
+    if (node->first_lparen_token != pattern->first_lparen_token)
+        return false;
+    if (node->second_lparen_token != pattern->second_lparen_token)
+        return false;
+    if (! AST::match(node->attribute_list, pattern->attribute_list, this))
+        return false;
+    if (node->first_rparen_token != pattern->first_rparen_token)
+        return false;
+    if (node->second_rparen_token != pattern->second_rparen_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ArrayDeclaratorAST *, ArrayDeclaratorAST *)
+bool ASTMatcher::match(AttributeAST *node, AttributeAST *pattern)
 {
+    if (node->identifier_token != pattern->identifier_token)
+        return false;
+    if (node->lparen_token != pattern->lparen_token)
+        return false;
+    if (node->tag_token != pattern->tag_token)
+        return false;
+    if (! AST::match(node->expression_list, pattern->expression_list, this))
+        return false;
+    if (node->rparen_token != pattern->rparen_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ArrayInitializerAST *, ArrayInitializerAST *)
+bool ASTMatcher::match(TypeofSpecifierAST *node, TypeofSpecifierAST *pattern)
 {
+    if (node->typeof_token != pattern->typeof_token)
+        return false;
+    if (node->lparen_token != pattern->lparen_token)
+        return false;
+    if (! AST::match(node->expression, pattern->expression, this))
+        return false;
+    if (node->rparen_token != pattern->rparen_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(AsmDefinitionAST *, AsmDefinitionAST *)
+bool ASTMatcher::match(DeclaratorAST *node, DeclaratorAST *pattern)
 {
+    if (! AST::match(node->attribute_list, pattern->attribute_list, this))
+        return false;
+    if (! AST::match(node->ptr_operator_list, pattern->ptr_operator_list, this))
+        return false;
+    if (! AST::match(node->core_declarator, pattern->core_declarator, this))
+        return false;
+    if (! AST::match(node->postfix_declarator_list, pattern->postfix_declarator_list, this))
+        return false;
+    if (! AST::match(node->post_attribute_list, pattern->post_attribute_list, this))
+        return false;
+    if (node->equals_token != pattern->equals_token)
+        return false;
+    if (! AST::match(node->initializer, pattern->initializer, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(AttributeSpecifierAST *, AttributeSpecifierAST *)
+bool ASTMatcher::match(SimpleDeclarationAST *node, SimpleDeclarationAST *pattern)
 {
+    if (node->qt_invokable_token != pattern->qt_invokable_token)
+        return false;
+    if (! AST::match(node->decl_specifier_list, pattern->decl_specifier_list, this))
+        return false;
+    if (! AST::match(node->declarator_list, pattern->declarator_list, this))
+        return false;
+    if (node->semicolon_token != pattern->semicolon_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(AttributeAST *, AttributeAST *)
+bool ASTMatcher::match(EmptyDeclarationAST *node, EmptyDeclarationAST *pattern)
 {
+    if (node->semicolon_token != pattern->semicolon_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(BaseSpecifierAST *, BaseSpecifierAST *)
+bool ASTMatcher::match(AccessDeclarationAST *node, AccessDeclarationAST *pattern)
 {
+    if (node->access_specifier_token != pattern->access_specifier_token)
+        return false;
+    if (node->slots_token != pattern->slots_token)
+        return false;
+    if (node->colon_token != pattern->colon_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(BinaryExpressionAST *, BinaryExpressionAST *)
+bool ASTMatcher::match(AsmDefinitionAST *node, AsmDefinitionAST *pattern)
 {
+    if (node->asm_token != pattern->asm_token)
+        return false;
+    if (node->volatile_token != pattern->volatile_token)
+        return false;
+    if (node->lparen_token != pattern->lparen_token)
+        return false;
+    if (node->rparen_token != pattern->rparen_token)
+        return false;
+    if (node->semicolon_token != pattern->semicolon_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(BoolLiteralAST *, BoolLiteralAST *)
+bool ASTMatcher::match(BaseSpecifierAST *node, BaseSpecifierAST *pattern)
 {
+    if (node->virtual_token != pattern->virtual_token)
+        return false;
+    if (node->access_specifier_token != pattern->access_specifier_token)
+        return false;
+    if (! AST::match(node->name, pattern->name, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(BreakStatementAST *, BreakStatementAST *)
+bool ASTMatcher::match(CompoundLiteralAST *node, CompoundLiteralAST *pattern)
 {
+    if (node->lparen_token != pattern->lparen_token)
+        return false;
+    if (! AST::match(node->type_id, pattern->type_id, this))
+        return false;
+    if (node->rparen_token != pattern->rparen_token)
+        return false;
+    if (! AST::match(node->initializer, pattern->initializer, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(CallAST *, CallAST *)
+bool ASTMatcher::match(QtMethodAST *node, QtMethodAST *pattern)
 {
+    if (node->method_token != pattern->method_token)
+        return false;
+    if (node->lparen_token != pattern->lparen_token)
+        return false;
+    if (! AST::match(node->declarator, pattern->declarator, this))
+        return false;
+    if (node->rparen_token != pattern->rparen_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(CaseStatementAST *, CaseStatementAST *)
+bool ASTMatcher::match(BinaryExpressionAST *node, BinaryExpressionAST *pattern)
 {
+    if (! AST::match(node->left_expression, pattern->left_expression, this))
+        return false;
+    if (node->binary_op_token != pattern->binary_op_token)
+        return false;
+    if (! AST::match(node->right_expression, pattern->right_expression, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(CastExpressionAST *, CastExpressionAST *)
+bool ASTMatcher::match(CastExpressionAST *node, CastExpressionAST *pattern)
 {
+    if (node->lparen_token != pattern->lparen_token)
+        return false;
+    if (! AST::match(node->type_id, pattern->type_id, this))
+        return false;
+    if (node->rparen_token != pattern->rparen_token)
+        return false;
+    if (! AST::match(node->expression, pattern->expression, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(CatchClauseAST *, CatchClauseAST *)
+bool ASTMatcher::match(ClassSpecifierAST *node, ClassSpecifierAST *pattern)
 {
+    if (node->classkey_token != pattern->classkey_token)
+        return false;
+    if (! AST::match(node->attribute_list, pattern->attribute_list, this))
+        return false;
+    if (! AST::match(node->name, pattern->name, this))
+        return false;
+    if (node->colon_token != pattern->colon_token)
+        return false;
+    if (! AST::match(node->base_clause_list, pattern->base_clause_list, this))
+        return false;
+    if (node->lbrace_token != pattern->lbrace_token)
+        return false;
+    if (! AST::match(node->member_specifier_list, pattern->member_specifier_list, this))
+        return false;
+    if (node->rbrace_token != pattern->rbrace_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ClassSpecifierAST *, ClassSpecifierAST *)
+bool ASTMatcher::match(CaseStatementAST *node, CaseStatementAST *pattern)
 {
+    if (node->case_token != pattern->case_token)
+        return false;
+    if (! AST::match(node->expression, pattern->expression, this))
+        return false;
+    if (node->colon_token != pattern->colon_token)
+        return false;
+    if (! AST::match(node->statement, pattern->statement, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(CompoundLiteralAST *, CompoundLiteralAST *)
+bool ASTMatcher::match(CompoundStatementAST *node, CompoundStatementAST *pattern)
 {
+    if (node->lbrace_token != pattern->lbrace_token)
+        return false;
+    if (! AST::match(node->statement_list, pattern->statement_list, this))
+        return false;
+    if (node->rbrace_token != pattern->rbrace_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(CompoundStatementAST *, CompoundStatementAST *)
+bool ASTMatcher::match(ConditionAST *node, ConditionAST *pattern)
 {
+    if (! AST::match(node->type_specifier_list, pattern->type_specifier_list, this))
+        return false;
+    if (! AST::match(node->declarator, pattern->declarator, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ConditionAST *, ConditionAST *)
+bool ASTMatcher::match(ConditionalExpressionAST *node, ConditionalExpressionAST *pattern)
 {
+    if (! AST::match(node->condition, pattern->condition, this))
+        return false;
+    if (node->question_token != pattern->question_token)
+        return false;
+    if (! AST::match(node->left_expression, pattern->left_expression, this))
+        return false;
+    if (node->colon_token != pattern->colon_token)
+        return false;
+    if (! AST::match(node->right_expression, pattern->right_expression, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ConditionalExpressionAST *, ConditionalExpressionAST *)
+bool ASTMatcher::match(CppCastExpressionAST *node, CppCastExpressionAST *pattern)
 {
+    if (node->cast_token != pattern->cast_token)
+        return false;
+    if (node->less_token != pattern->less_token)
+        return false;
+    if (! AST::match(node->type_id, pattern->type_id, this))
+        return false;
+    if (node->greater_token != pattern->greater_token)
+        return false;
+    if (node->lparen_token != pattern->lparen_token)
+        return false;
+    if (! AST::match(node->expression, pattern->expression, this))
+        return false;
+    if (node->rparen_token != pattern->rparen_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ContinueStatementAST *, ContinueStatementAST *)
+bool ASTMatcher::match(CtorInitializerAST *node, CtorInitializerAST *pattern)
 {
+    if (node->colon_token != pattern->colon_token)
+        return false;
+    if (! AST::match(node->member_initializer_list, pattern->member_initializer_list, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ConversionFunctionIdAST *, ConversionFunctionIdAST *)
+bool ASTMatcher::match(DeclarationStatementAST *node, DeclarationStatementAST *pattern)
 {
+    if (! AST::match(node->declaration, pattern->declaration, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(CppCastExpressionAST *, CppCastExpressionAST *)
+bool ASTMatcher::match(DeclaratorIdAST *node, DeclaratorIdAST *pattern)
 {
+    if (! AST::match(node->name, pattern->name, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(CtorInitializerAST *, CtorInitializerAST *)
+bool ASTMatcher::match(NestedDeclaratorAST *node, NestedDeclaratorAST *pattern)
 {
+    if (node->lparen_token != pattern->lparen_token)
+        return false;
+    if (! AST::match(node->declarator, pattern->declarator, this))
+        return false;
+    if (node->rparen_token != pattern->rparen_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(DeclaratorAST *, DeclaratorAST *)
+bool ASTMatcher::match(FunctionDeclaratorAST *node, FunctionDeclaratorAST *pattern)
 {
+    if (node->lparen_token != pattern->lparen_token)
+        return false;
+    if (! AST::match(node->parameters, pattern->parameters, this))
+        return false;
+    if (node->rparen_token != pattern->rparen_token)
+        return false;
+    if (! AST::match(node->cv_qualifier_list, pattern->cv_qualifier_list, this))
+        return false;
+    if (! AST::match(node->exception_specification, pattern->exception_specification, this))
+        return false;
+    if (! AST::match(node->as_cpp_initializer, pattern->as_cpp_initializer, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(DeclarationStatementAST *, DeclarationStatementAST *)
+bool ASTMatcher::match(ArrayDeclaratorAST *node, ArrayDeclaratorAST *pattern)
 {
+    if (node->lbracket_token != pattern->lbracket_token)
+        return false;
+    if (! AST::match(node->expression, pattern->expression, this))
+        return false;
+    if (node->rbracket_token != pattern->rbracket_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(DeclaratorIdAST *, DeclaratorIdAST *)
+bool ASTMatcher::match(DeleteExpressionAST *node, DeleteExpressionAST *pattern)
 {
+    if (node->scope_token != pattern->scope_token)
+        return false;
+    if (node->delete_token != pattern->delete_token)
+        return false;
+    if (node->lbracket_token != pattern->lbracket_token)
+        return false;
+    if (node->rbracket_token != pattern->rbracket_token)
+        return false;
+    if (! AST::match(node->expression, pattern->expression, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(DeleteExpressionAST *, DeleteExpressionAST *)
+bool ASTMatcher::match(DoStatementAST *node, DoStatementAST *pattern)
 {
+    if (node->do_token != pattern->do_token)
+        return false;
+    if (! AST::match(node->statement, pattern->statement, this))
+        return false;
+    if (node->while_token != pattern->while_token)
+        return false;
+    if (node->lparen_token != pattern->lparen_token)
+        return false;
+    if (! AST::match(node->expression, pattern->expression, this))
+        return false;
+    if (node->rparen_token != pattern->rparen_token)
+        return false;
+    if (node->semicolon_token != pattern->semicolon_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(DestructorNameAST *, DestructorNameAST *)
+bool ASTMatcher::match(NamedTypeSpecifierAST *node, NamedTypeSpecifierAST *pattern)
 {
+    if (! AST::match(node->name, pattern->name, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(DoStatementAST *, DoStatementAST *)
+bool ASTMatcher::match(ElaboratedTypeSpecifierAST *node, ElaboratedTypeSpecifierAST *pattern)
 {
+    if (node->classkey_token != pattern->classkey_token)
+        return false;
+    if (! AST::match(node->name, pattern->name, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ElaboratedTypeSpecifierAST *, ElaboratedTypeSpecifierAST *)
+bool ASTMatcher::match(EnumSpecifierAST *node, EnumSpecifierAST *pattern)
 {
+    if (node->enum_token != pattern->enum_token)
+        return false;
+    if (! AST::match(node->name, pattern->name, this))
+        return false;
+    if (node->lbrace_token != pattern->lbrace_token)
+        return false;
+    if (! AST::match(node->enumerator_list, pattern->enumerator_list, this))
+        return false;
+    if (node->rbrace_token != pattern->rbrace_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(EmptyDeclarationAST *, EmptyDeclarationAST *)
+bool ASTMatcher::match(EnumeratorAST *node, EnumeratorAST *pattern)
 {
+    if (node->identifier_token != pattern->identifier_token)
+        return false;
+    if (node->equal_token != pattern->equal_token)
+        return false;
+    if (! AST::match(node->expression, pattern->expression, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(EnumSpecifierAST *, EnumSpecifierAST *)
+bool ASTMatcher::match(ExceptionDeclarationAST *node, ExceptionDeclarationAST *pattern)
 {
+    if (! AST::match(node->type_specifier_list, pattern->type_specifier_list, this))
+        return false;
+    if (! AST::match(node->declarator, pattern->declarator, this))
+        return false;
+    if (node->dot_dot_dot_token != pattern->dot_dot_dot_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(EnumeratorAST *, EnumeratorAST *)
+bool ASTMatcher::match(ExceptionSpecificationAST *node, ExceptionSpecificationAST *pattern)
 {
+    if (node->throw_token != pattern->throw_token)
+        return false;
+    if (node->lparen_token != pattern->lparen_token)
+        return false;
+    if (node->dot_dot_dot_token != pattern->dot_dot_dot_token)
+        return false;
+    if (! AST::match(node->type_id_list, pattern->type_id_list, this))
+        return false;
+    if (node->rparen_token != pattern->rparen_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ExceptionDeclarationAST *, ExceptionDeclarationAST *)
+bool ASTMatcher::match(ExpressionOrDeclarationStatementAST *node, ExpressionOrDeclarationStatementAST *pattern)
 {
+    if (! AST::match(node->expression, pattern->expression, this))
+        return false;
+    if (! AST::match(node->declaration, pattern->declaration, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ExceptionSpecificationAST *, ExceptionSpecificationAST *)
+bool ASTMatcher::match(ExpressionStatementAST *node, ExpressionStatementAST *pattern)
 {
+    if (! AST::match(node->expression, pattern->expression, this))
+        return false;
+    if (node->semicolon_token != pattern->semicolon_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ExpressionOrDeclarationStatementAST *, ExpressionOrDeclarationStatementAST *)
+bool ASTMatcher::match(FunctionDefinitionAST *node, FunctionDefinitionAST *pattern)
 {
+    if (node->qt_invokable_token != pattern->qt_invokable_token)
+        return false;
+    if (! AST::match(node->decl_specifier_list, pattern->decl_specifier_list, this))
+        return false;
+    if (! AST::match(node->declarator, pattern->declarator, this))
+        return false;
+    if (! AST::match(node->ctor_initializer, pattern->ctor_initializer, this))
+        return false;
+    if (! AST::match(node->function_body, pattern->function_body, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ExpressionStatementAST *, ExpressionStatementAST *)
+bool ASTMatcher::match(ForeachStatementAST *node, ForeachStatementAST *pattern)
 {
+    if (node->foreach_token != pattern->foreach_token)
+        return false;
+    if (node->lparen_token != pattern->lparen_token)
+        return false;
+    if (! AST::match(node->type_specifier_list, pattern->type_specifier_list, this))
+        return false;
+    if (! AST::match(node->declarator, pattern->declarator, this))
+        return false;
+    if (! AST::match(node->initializer, pattern->initializer, this))
+        return false;
+    if (node->comma_token != pattern->comma_token)
+        return false;
+    if (! AST::match(node->expression, pattern->expression, this))
+        return false;
+    if (node->rparen_token != pattern->rparen_token)
+        return false;
+    if (! AST::match(node->statement, pattern->statement, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ForeachStatementAST *, ForeachStatementAST *)
+bool ASTMatcher::match(ForStatementAST *node, ForStatementAST *pattern)
 {
+    if (node->for_token != pattern->for_token)
+        return false;
+    if (node->lparen_token != pattern->lparen_token)
+        return false;
+    if (! AST::match(node->initializer, pattern->initializer, this))
+        return false;
+    if (! AST::match(node->condition, pattern->condition, this))
+        return false;
+    if (node->semicolon_token != pattern->semicolon_token)
+        return false;
+    if (! AST::match(node->expression, pattern->expression, this))
+        return false;
+    if (node->rparen_token != pattern->rparen_token)
+        return false;
+    if (! AST::match(node->statement, pattern->statement, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ForStatementAST *, ForStatementAST *)
+bool ASTMatcher::match(IfStatementAST *node, IfStatementAST *pattern)
 {
+    if (node->if_token != pattern->if_token)
+        return false;
+    if (node->lparen_token != pattern->lparen_token)
+        return false;
+    if (! AST::match(node->condition, pattern->condition, this))
+        return false;
+    if (node->rparen_token != pattern->rparen_token)
+        return false;
+    if (! AST::match(node->statement, pattern->statement, this))
+        return false;
+    if (node->else_token != pattern->else_token)
+        return false;
+    if (! AST::match(node->else_statement, pattern->else_statement, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(FunctionDeclaratorAST *, FunctionDeclaratorAST *)
+bool ASTMatcher::match(ArrayInitializerAST *node, ArrayInitializerAST *pattern)
 {
+    if (node->lbrace_token != pattern->lbrace_token)
+        return false;
+    if (! AST::match(node->expression_list, pattern->expression_list, this))
+        return false;
+    if (node->rbrace_token != pattern->rbrace_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(FunctionDefinitionAST *, FunctionDefinitionAST *)
+bool ASTMatcher::match(LabeledStatementAST *node, LabeledStatementAST *pattern)
 {
+    if (node->label_token != pattern->label_token)
+        return false;
+    if (node->colon_token != pattern->colon_token)
+        return false;
+    if (! AST::match(node->statement, pattern->statement, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(GotoStatementAST *, GotoStatementAST *)
+bool ASTMatcher::match(LinkageBodyAST *node, LinkageBodyAST *pattern)
 {
+    if (node->lbrace_token != pattern->lbrace_token)
+        return false;
+    if (! AST::match(node->declaration_list, pattern->declaration_list, this))
+        return false;
+    if (node->rbrace_token != pattern->rbrace_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(IfStatementAST *, IfStatementAST *)
+bool ASTMatcher::match(LinkageSpecificationAST *node, LinkageSpecificationAST *pattern)
 {
+    if (node->extern_token != pattern->extern_token)
+        return false;
+    if (node->extern_type_token != pattern->extern_type_token)
+        return false;
+    if (! AST::match(node->declaration, pattern->declaration, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(LabeledStatementAST *, LabeledStatementAST *)
+bool ASTMatcher::match(MemInitializerAST *node, MemInitializerAST *pattern)
 {
+    if (! AST::match(node->name, pattern->name, this))
+        return false;
+    if (node->lparen_token != pattern->lparen_token)
+        return false;
+    if (! AST::match(node->expression, pattern->expression, this))
+        return false;
+    if (node->rparen_token != pattern->rparen_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(LinkageBodyAST *, LinkageBodyAST *)
+bool ASTMatcher::match(NestedNameSpecifierAST *node, NestedNameSpecifierAST *pattern)
 {
+    if (! AST::match(node->class_or_namespace_name, pattern->class_or_namespace_name, this))
+        return false;
+    if (node->scope_token != pattern->scope_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(LinkageSpecificationAST *, LinkageSpecificationAST *)
+bool ASTMatcher::match(QualifiedNameAST *node, QualifiedNameAST *pattern)
 {
+    if (node->global_scope_token != pattern->global_scope_token)
+        return false;
+    if (! AST::match(node->nested_name_specifier_list, pattern->nested_name_specifier_list, this))
+        return false;
+    if (! AST::match(node->unqualified_name, pattern->unqualified_name, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(MemInitializerAST *, MemInitializerAST *)
+bool ASTMatcher::match(OperatorFunctionIdAST *node, OperatorFunctionIdAST *pattern)
 {
+    if (node->operator_token != pattern->operator_token)
+        return false;
+    if (! AST::match(node->op, pattern->op, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(MemberAccessAST *, MemberAccessAST *)
+bool ASTMatcher::match(ConversionFunctionIdAST *node, ConversionFunctionIdAST *pattern)
 {
+    if (node->operator_token != pattern->operator_token)
+        return false;
+    if (! AST::match(node->type_specifier_list, pattern->type_specifier_list, this))
+        return false;
+    if (! AST::match(node->ptr_operator_list, pattern->ptr_operator_list, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(NamedTypeSpecifierAST *, NamedTypeSpecifierAST *)
+bool ASTMatcher::match(SimpleNameAST *node, SimpleNameAST *pattern)
 {
+    if (node->identifier_token != pattern->identifier_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(NamespaceAST *, NamespaceAST *)
+bool ASTMatcher::match(DestructorNameAST *node, DestructorNameAST *pattern)
 {
+    if (node->tilde_token != pattern->tilde_token)
+        return false;
+    if (node->identifier_token != pattern->identifier_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(NamespaceAliasDefinitionAST *, NamespaceAliasDefinitionAST *)
+bool ASTMatcher::match(TemplateIdAST *node, TemplateIdAST *pattern)
 {
+    if (node->identifier_token != pattern->identifier_token)
+        return false;
+    if (node->less_token != pattern->less_token)
+        return false;
+    if (! AST::match(node->template_argument_list, pattern->template_argument_list, this))
+        return false;
+    if (node->greater_token != pattern->greater_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(NestedDeclaratorAST *, NestedDeclaratorAST *)
+bool ASTMatcher::match(NamespaceAST *node, NamespaceAST *pattern)
 {
+    if (node->namespace_token != pattern->namespace_token)
+        return false;
+    if (node->identifier_token != pattern->identifier_token)
+        return false;
+    if (! AST::match(node->attribute_list, pattern->attribute_list, this))
+        return false;
+    if (! AST::match(node->linkage_body, pattern->linkage_body, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(NestedExpressionAST *, NestedExpressionAST *)
+bool ASTMatcher::match(NamespaceAliasDefinitionAST *node, NamespaceAliasDefinitionAST *pattern)
 {
+    if (node->namespace_token != pattern->namespace_token)
+        return false;
+    if (node->namespace_name_token != pattern->namespace_name_token)
+        return false;
+    if (node->equal_token != pattern->equal_token)
+        return false;
+    if (! AST::match(node->name, pattern->name, this))
+        return false;
+    if (node->semicolon_token != pattern->semicolon_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(NestedNameSpecifierAST *, NestedNameSpecifierAST *)
+bool ASTMatcher::match(NewPlacementAST *node, NewPlacementAST *pattern)
 {
+    if (node->lparen_token != pattern->lparen_token)
+        return false;
+    if (! AST::match(node->expression_list, pattern->expression_list, this))
+        return false;
+    if (node->rparen_token != pattern->rparen_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(NewPlacementAST *, NewPlacementAST *)
+bool ASTMatcher::match(NewArrayDeclaratorAST *node, NewArrayDeclaratorAST *pattern)
 {
+    if (node->lbracket_token != pattern->lbracket_token)
+        return false;
+    if (! AST::match(node->expression, pattern->expression, this))
+        return false;
+    if (node->rbracket_token != pattern->rbracket_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(NewArrayDeclaratorAST *, NewArrayDeclaratorAST *)
+bool ASTMatcher::match(NewExpressionAST *node, NewExpressionAST *pattern)
 {
+    if (node->scope_token != pattern->scope_token)
+        return false;
+    if (node->new_token != pattern->new_token)
+        return false;
+    if (! AST::match(node->new_placement, pattern->new_placement, this))
+        return false;
+    if (node->lparen_token != pattern->lparen_token)
+        return false;
+    if (! AST::match(node->type_id, pattern->type_id, this))
+        return false;
+    if (node->rparen_token != pattern->rparen_token)
+        return false;
+    if (! AST::match(node->new_type_id, pattern->new_type_id, this))
+        return false;
+    if (! AST::match(node->new_initializer, pattern->new_initializer, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(NewExpressionAST *, NewExpressionAST *)
+bool ASTMatcher::match(NewInitializerAST *node, NewInitializerAST *pattern)
 {
+    if (node->lparen_token != pattern->lparen_token)
+        return false;
+    if (! AST::match(node->expression, pattern->expression, this))
+        return false;
+    if (node->rparen_token != pattern->rparen_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(NewInitializerAST *, NewInitializerAST *)
+bool ASTMatcher::match(NewTypeIdAST *node, NewTypeIdAST *pattern)
 {
+    if (! AST::match(node->type_specifier_list, pattern->type_specifier_list, this))
+        return false;
+    if (! AST::match(node->ptr_operator_list, pattern->ptr_operator_list, this))
+        return false;
+    if (! AST::match(node->new_array_declarator_list, pattern->new_array_declarator_list, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(NewTypeIdAST *, NewTypeIdAST *)
+bool ASTMatcher::match(OperatorAST *node, OperatorAST *pattern)
 {
+    if (node->op_token != pattern->op_token)
+        return false;
+    if (node->open_token != pattern->open_token)
+        return false;
+    if (node->close_token != pattern->close_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(NumericLiteralAST *, NumericLiteralAST *)
+bool ASTMatcher::match(ParameterDeclarationAST *node, ParameterDeclarationAST *pattern)
 {
+    if (! AST::match(node->type_specifier_list, pattern->type_specifier_list, this))
+        return false;
+    if (! AST::match(node->declarator, pattern->declarator, this))
+        return false;
+    if (node->equal_token != pattern->equal_token)
+        return false;
+    if (! AST::match(node->expression, pattern->expression, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(OperatorAST *, OperatorAST *)
+bool ASTMatcher::match(ParameterDeclarationClauseAST *node, ParameterDeclarationClauseAST *pattern)
 {
+    if (! AST::match(node->parameter_declaration_list, pattern->parameter_declaration_list, this))
+        return false;
+    if (node->dot_dot_dot_token != pattern->dot_dot_dot_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(OperatorFunctionIdAST *, OperatorFunctionIdAST *)
+bool ASTMatcher::match(CallAST *node, CallAST *pattern)
 {
+    if (node->lparen_token != pattern->lparen_token)
+        return false;
+    if (! AST::match(node->expression_list, pattern->expression_list, this))
+        return false;
+    if (node->rparen_token != pattern->rparen_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ParameterDeclarationAST *, ParameterDeclarationAST *)
+bool ASTMatcher::match(ArrayAccessAST *node, ArrayAccessAST *pattern)
 {
+    if (node->lbracket_token != pattern->lbracket_token)
+        return false;
+    if (! AST::match(node->expression, pattern->expression, this))
+        return false;
+    if (node->rbracket_token != pattern->rbracket_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ParameterDeclarationClauseAST *, ParameterDeclarationClauseAST *)
+bool ASTMatcher::match(PostIncrDecrAST *node, PostIncrDecrAST *pattern)
 {
+    if (node->incr_decr_token != pattern->incr_decr_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(PointerAST *, PointerAST *)
+bool ASTMatcher::match(MemberAccessAST *node, MemberAccessAST *pattern)
 {
+    if (node->access_token != pattern->access_token)
+        return false;
+    if (node->template_token != pattern->template_token)
+        return false;
+    if (! AST::match(node->member_name, pattern->member_name, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(PointerToMemberAST *, PointerToMemberAST *)
+bool ASTMatcher::match(TypeidExpressionAST *node, TypeidExpressionAST *pattern)
 {
+    if (node->typeid_token != pattern->typeid_token)
+        return false;
+    if (node->lparen_token != pattern->lparen_token)
+        return false;
+    if (! AST::match(node->expression, pattern->expression, this))
+        return false;
+    if (node->rparen_token != pattern->rparen_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(PostIncrDecrAST *, PostIncrDecrAST *)
+bool ASTMatcher::match(TypenameCallExpressionAST *node, TypenameCallExpressionAST *pattern)
 {
+    if (node->typename_token != pattern->typename_token)
+        return false;
+    if (! AST::match(node->name, pattern->name, this))
+        return false;
+    if (node->lparen_token != pattern->lparen_token)
+        return false;
+    if (! AST::match(node->expression_list, pattern->expression_list, this))
+        return false;
+    if (node->rparen_token != pattern->rparen_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(PostfixExpressionAST *, PostfixExpressionAST *)
+bool ASTMatcher::match(TypeConstructorCallAST *node, TypeConstructorCallAST *pattern)
 {
+    if (! AST::match(node->type_specifier_list, pattern->type_specifier_list, this))
+        return false;
+    if (node->lparen_token != pattern->lparen_token)
+        return false;
+    if (! AST::match(node->expression_list, pattern->expression_list, this))
+        return false;
+    if (node->rparen_token != pattern->rparen_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(QualifiedNameAST *, QualifiedNameAST *)
+bool ASTMatcher::match(PostfixExpressionAST *node, PostfixExpressionAST *pattern)
 {
+    if (! AST::match(node->base_expression, pattern->base_expression, this))
+        return false;
+    if (! AST::match(node->postfix_expression_list, pattern->postfix_expression_list, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ReferenceAST *, ReferenceAST *)
+bool ASTMatcher::match(PointerToMemberAST *node, PointerToMemberAST *pattern)
 {
+    if (node->global_scope_token != pattern->global_scope_token)
+        return false;
+    if (! AST::match(node->nested_name_specifier_list, pattern->nested_name_specifier_list, this))
+        return false;
+    if (node->star_token != pattern->star_token)
+        return false;
+    if (! AST::match(node->cv_qualifier_list, pattern->cv_qualifier_list, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ReturnStatementAST *, ReturnStatementAST *)
+bool ASTMatcher::match(PointerAST *node, PointerAST *pattern)
 {
+    if (node->star_token != pattern->star_token)
+        return false;
+    if (! AST::match(node->cv_qualifier_list, pattern->cv_qualifier_list, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(SimpleDeclarationAST *, SimpleDeclarationAST *)
+bool ASTMatcher::match(ReferenceAST *node, ReferenceAST *pattern)
 {
+    if (node->amp_token != pattern->amp_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(SimpleNameAST *, SimpleNameAST *)
+bool ASTMatcher::match(BreakStatementAST *node, BreakStatementAST *pattern)
 {
+    if (node->break_token != pattern->break_token)
+        return false;
+    if (node->semicolon_token != pattern->semicolon_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(SimpleSpecifierAST *, SimpleSpecifierAST *)
+bool ASTMatcher::match(ContinueStatementAST *node, ContinueStatementAST *pattern)
 {
+    if (node->continue_token != pattern->continue_token)
+        return false;
+    if (node->semicolon_token != pattern->semicolon_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(SizeofExpressionAST *, SizeofExpressionAST *)
+bool ASTMatcher::match(GotoStatementAST *node, GotoStatementAST *pattern)
 {
+    if (node->goto_token != pattern->goto_token)
+        return false;
+    if (node->identifier_token != pattern->identifier_token)
+        return false;
+    if (node->semicolon_token != pattern->semicolon_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(StringLiteralAST *, StringLiteralAST *)
+bool ASTMatcher::match(ReturnStatementAST *node, ReturnStatementAST *pattern)
 {
+    if (node->return_token != pattern->return_token)
+        return false;
+    if (! AST::match(node->expression, pattern->expression, this))
+        return false;
+    if (node->semicolon_token != pattern->semicolon_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(SwitchStatementAST *, SwitchStatementAST *)
+bool ASTMatcher::match(SizeofExpressionAST *node, SizeofExpressionAST *pattern)
 {
+    if (node->sizeof_token != pattern->sizeof_token)
+        return false;
+    if (node->lparen_token != pattern->lparen_token)
+        return false;
+    if (! AST::match(node->expression, pattern->expression, this))
+        return false;
+    if (node->rparen_token != pattern->rparen_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(TemplateDeclarationAST *, TemplateDeclarationAST *)
+bool ASTMatcher::match(NumericLiteralAST *node, NumericLiteralAST *pattern)
 {
+    if (node->literal_token != pattern->literal_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(TemplateIdAST *, TemplateIdAST *)
+bool ASTMatcher::match(BoolLiteralAST *node, BoolLiteralAST *pattern)
 {
+    if (node->literal_token != pattern->literal_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(TemplateTypeParameterAST *, TemplateTypeParameterAST *)
+bool ASTMatcher::match(ThisExpressionAST *node, ThisExpressionAST *pattern)
 {
+    if (node->this_token != pattern->this_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ThisExpressionAST *, ThisExpressionAST *)
+bool ASTMatcher::match(NestedExpressionAST *node, NestedExpressionAST *pattern)
 {
+    if (node->lparen_token != pattern->lparen_token)
+        return false;
+    if (! AST::match(node->expression, pattern->expression, this))
+        return false;
+    if (node->rparen_token != pattern->rparen_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ThrowExpressionAST *, ThrowExpressionAST *)
+bool ASTMatcher::match(StringLiteralAST *node, StringLiteralAST *pattern)
 {
+    if (node->literal_token != pattern->literal_token)
+        return false;
+    if (! AST::match(node->next, pattern->next, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(TranslationUnitAST *, TranslationUnitAST *)
+bool ASTMatcher::match(SwitchStatementAST *node, SwitchStatementAST *pattern)
 {
+    if (node->switch_token != pattern->switch_token)
+        return false;
+    if (node->lparen_token != pattern->lparen_token)
+        return false;
+    if (! AST::match(node->condition, pattern->condition, this))
+        return false;
+    if (node->rparen_token != pattern->rparen_token)
+        return false;
+    if (! AST::match(node->statement, pattern->statement, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(TryBlockStatementAST *, TryBlockStatementAST *)
+bool ASTMatcher::match(TemplateDeclarationAST *node, TemplateDeclarationAST *pattern)
 {
+    if (node->export_token != pattern->export_token)
+        return false;
+    if (node->template_token != pattern->template_token)
+        return false;
+    if (node->less_token != pattern->less_token)
+        return false;
+    if (! AST::match(node->template_parameter_list, pattern->template_parameter_list, this))
+        return false;
+    if (node->greater_token != pattern->greater_token)
+        return false;
+    if (! AST::match(node->declaration, pattern->declaration, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(TypeConstructorCallAST *, TypeConstructorCallAST *)
+bool ASTMatcher::match(ThrowExpressionAST *node, ThrowExpressionAST *pattern)
 {
+    if (node->throw_token != pattern->throw_token)
+        return false;
+    if (! AST::match(node->expression, pattern->expression, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(TypeIdAST *, TypeIdAST *)
+bool ASTMatcher::match(TranslationUnitAST *node, TranslationUnitAST *pattern)
 {
+    if (! AST::match(node->declaration_list, pattern->declaration_list, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(TypeidExpressionAST *, TypeidExpressionAST *)
+bool ASTMatcher::match(TryBlockStatementAST *node, TryBlockStatementAST *pattern)
 {
+    if (node->try_token != pattern->try_token)
+        return false;
+    if (! AST::match(node->statement, pattern->statement, this))
+        return false;
+    if (! AST::match(node->catch_clause_list, pattern->catch_clause_list, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(TypeofSpecifierAST *, TypeofSpecifierAST *)
+bool ASTMatcher::match(CatchClauseAST *node, CatchClauseAST *pattern)
 {
+    if (node->catch_token != pattern->catch_token)
+        return false;
+    if (node->lparen_token != pattern->lparen_token)
+        return false;
+    if (! AST::match(node->exception_declaration, pattern->exception_declaration, this))
+        return false;
+    if (node->rparen_token != pattern->rparen_token)
+        return false;
+    if (! AST::match(node->statement, pattern->statement, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(TypenameCallExpressionAST *, TypenameCallExpressionAST *)
+bool ASTMatcher::match(TypeIdAST *node, TypeIdAST *pattern)
 {
+    if (! AST::match(node->type_specifier_list, pattern->type_specifier_list, this))
+        return false;
+    if (! AST::match(node->declarator, pattern->declarator, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(TypenameTypeParameterAST *, TypenameTypeParameterAST *)
+bool ASTMatcher::match(TypenameTypeParameterAST *node, TypenameTypeParameterAST *pattern)
 {
+    if (node->classkey_token != pattern->classkey_token)
+        return false;
+    if (! AST::match(node->name, pattern->name, this))
+        return false;
+    if (node->equal_token != pattern->equal_token)
+        return false;
+    if (! AST::match(node->type_id, pattern->type_id, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(UnaryExpressionAST *, UnaryExpressionAST *)
+bool ASTMatcher::match(TemplateTypeParameterAST *node, TemplateTypeParameterAST *pattern)
 {
+    if (node->template_token != pattern->template_token)
+        return false;
+    if (node->less_token != pattern->less_token)
+        return false;
+    if (! AST::match(node->template_parameter_list, pattern->template_parameter_list, this))
+        return false;
+    if (node->greater_token != pattern->greater_token)
+        return false;
+    if (node->class_token != pattern->class_token)
+        return false;
+    if (! AST::match(node->name, pattern->name, this))
+        return false;
+    if (node->equal_token != pattern->equal_token)
+        return false;
+    if (! AST::match(node->type_id, pattern->type_id, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(UsingAST *, UsingAST *)
+bool ASTMatcher::match(UnaryExpressionAST *node, UnaryExpressionAST *pattern)
 {
+    if (node->unary_op_token != pattern->unary_op_token)
+        return false;
+    if (! AST::match(node->expression, pattern->expression, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(UsingDirectiveAST *, UsingDirectiveAST *)
+bool ASTMatcher::match(UsingAST *node, UsingAST *pattern)
 {
+    if (node->using_token != pattern->using_token)
+        return false;
+    if (node->typename_token != pattern->typename_token)
+        return false;
+    if (! AST::match(node->name, pattern->name, this))
+        return false;
+    if (node->semicolon_token != pattern->semicolon_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(WhileStatementAST *, WhileStatementAST *)
+bool ASTMatcher::match(UsingDirectiveAST *node, UsingDirectiveAST *pattern)
 {
+    if (node->using_token != pattern->using_token)
+        return false;
+    if (node->namespace_token != pattern->namespace_token)
+        return false;
+    if (! AST::match(node->name, pattern->name, this))
+        return false;
+    if (node->semicolon_token != pattern->semicolon_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(QtMethodAST *, QtMethodAST *)
+bool ASTMatcher::match(WhileStatementAST *node, WhileStatementAST *pattern)
 {
+    if (node->while_token != pattern->while_token)
+        return false;
+    if (node->lparen_token != pattern->lparen_token)
+        return false;
+    if (! AST::match(node->condition, pattern->condition, this))
+        return false;
+    if (node->rparen_token != pattern->rparen_token)
+        return false;
+    if (! AST::match(node->statement, pattern->statement, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ObjCClassDeclarationAST *, ObjCClassDeclarationAST *)
+bool ASTMatcher::match(ObjCClassForwardDeclarationAST *node, ObjCClassForwardDeclarationAST *pattern)
 {
+    if (! AST::match(node->attribute_list, pattern->attribute_list, this))
+        return false;
+    if (node->class_token != pattern->class_token)
+        return false;
+    if (! AST::match(node->identifier_list, pattern->identifier_list, this))
+        return false;
+    if (node->semicolon_token != pattern->semicolon_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ObjCClassForwardDeclarationAST *, ObjCClassForwardDeclarationAST *)
+bool ASTMatcher::match(ObjCClassDeclarationAST *node, ObjCClassDeclarationAST *pattern)
 {
+    if (! AST::match(node->attribute_list, pattern->attribute_list, this))
+        return false;
+    if (node->interface_token != pattern->interface_token)
+        return false;
+    if (node->implementation_token != pattern->implementation_token)
+        return false;
+    if (! AST::match(node->class_name, pattern->class_name, this))
+        return false;
+    if (node->lparen_token != pattern->lparen_token)
+        return false;
+    if (! AST::match(node->category_name, pattern->category_name, this))
+        return false;
+    if (node->rparen_token != pattern->rparen_token)
+        return false;
+    if (node->colon_token != pattern->colon_token)
+        return false;
+    if (! AST::match(node->superclass, pattern->superclass, this))
+        return false;
+    if (! AST::match(node->protocol_refs, pattern->protocol_refs, this))
+        return false;
+    if (! AST::match(node->inst_vars_decl, pattern->inst_vars_decl, this))
+        return false;
+    if (! AST::match(node->member_declaration_list, pattern->member_declaration_list, this))
+        return false;
+    if (node->end_token != pattern->end_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ObjCProtocolDeclarationAST *, ObjCProtocolDeclarationAST *)
+bool ASTMatcher::match(ObjCProtocolForwardDeclarationAST *node, ObjCProtocolForwardDeclarationAST *pattern)
 {
+    if (! AST::match(node->attribute_list, pattern->attribute_list, this))
+        return false;
+    if (node->protocol_token != pattern->protocol_token)
+        return false;
+    if (! AST::match(node->identifier_list, pattern->identifier_list, this))
+        return false;
+    if (node->semicolon_token != pattern->semicolon_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ObjCProtocolForwardDeclarationAST *, ObjCProtocolForwardDeclarationAST *)
+bool ASTMatcher::match(ObjCProtocolDeclarationAST *node, ObjCProtocolDeclarationAST *pattern)
 {
+    if (! AST::match(node->attribute_list, pattern->attribute_list, this))
+        return false;
+    if (node->protocol_token != pattern->protocol_token)
+        return false;
+    if (! AST::match(node->name, pattern->name, this))
+        return false;
+    if (! AST::match(node->protocol_refs, pattern->protocol_refs, this))
+        return false;
+    if (! AST::match(node->member_declaration_list, pattern->member_declaration_list, this))
+        return false;
+    if (node->end_token != pattern->end_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ObjCProtocolRefsAST *, ObjCProtocolRefsAST *)
+bool ASTMatcher::match(ObjCProtocolRefsAST *node, ObjCProtocolRefsAST *pattern)
 {
+    if (node->less_token != pattern->less_token)
+        return false;
+    if (! AST::match(node->identifier_list, pattern->identifier_list, this))
+        return false;
+    if (node->greater_token != pattern->greater_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ObjCMessageExpressionAST *, ObjCMessageExpressionAST *)
+bool ASTMatcher::match(ObjCMessageArgumentAST *node, ObjCMessageArgumentAST *pattern)
 {
+    if (! AST::match(node->parameter_value_expression, pattern->parameter_value_expression, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ObjCMessageArgumentAST *, ObjCMessageArgumentAST *)
+bool ASTMatcher::match(ObjCMessageExpressionAST *node, ObjCMessageExpressionAST *pattern)
 {
+    if (node->lbracket_token != pattern->lbracket_token)
+        return false;
+    if (! AST::match(node->receiver_expression, pattern->receiver_expression, this))
+        return false;
+    if (! AST::match(node->selector, pattern->selector, this))
+        return false;
+    if (! AST::match(node->argument_list, pattern->argument_list, this))
+        return false;
+    if (node->rbracket_token != pattern->rbracket_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ObjCProtocolExpressionAST *, ObjCProtocolExpressionAST *)
+bool ASTMatcher::match(ObjCProtocolExpressionAST *node, ObjCProtocolExpressionAST *pattern)
 {
+    if (node->protocol_token != pattern->protocol_token)
+        return false;
+    if (node->lparen_token != pattern->lparen_token)
+        return false;
+    if (node->identifier_token != pattern->identifier_token)
+        return false;
+    if (node->rparen_token != pattern->rparen_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ObjCTypeNameAST *, ObjCTypeNameAST *)
+bool ASTMatcher::match(ObjCTypeNameAST *node, ObjCTypeNameAST *pattern)
 {
+    if (node->lparen_token != pattern->lparen_token)
+        return false;
+    if (! AST::match(node->type_id, pattern->type_id, this))
+        return false;
+    if (node->rparen_token != pattern->rparen_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ObjCEncodeExpressionAST *, ObjCEncodeExpressionAST *)
+bool ASTMatcher::match(ObjCEncodeExpressionAST *node, ObjCEncodeExpressionAST *pattern)
 {
+    if (node->encode_token != pattern->encode_token)
+        return false;
+    if (! AST::match(node->type_name, pattern->type_name, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ObjCSelectorWithoutArgumentsAST *, ObjCSelectorWithoutArgumentsAST *)
+bool ASTMatcher::match(ObjCSelectorWithoutArgumentsAST *node, ObjCSelectorWithoutArgumentsAST *pattern)
 {
+    if (node->name_token != pattern->name_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ObjCSelectorArgumentAST *, ObjCSelectorArgumentAST *)
+bool ASTMatcher::match(ObjCSelectorArgumentAST *node, ObjCSelectorArgumentAST *pattern)
 {
+    if (node->name_token != pattern->name_token)
+        return false;
+    if (node->colon_token != pattern->colon_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ObjCSelectorWithArgumentsAST *, ObjCSelectorWithArgumentsAST *)
+bool ASTMatcher::match(ObjCSelectorWithArgumentsAST *node, ObjCSelectorWithArgumentsAST *pattern)
 {
+    if (! AST::match(node->selector_argument_list, pattern->selector_argument_list, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ObjCSelectorExpressionAST *, ObjCSelectorExpressionAST *)
+bool ASTMatcher::match(ObjCSelectorExpressionAST *node, ObjCSelectorExpressionAST *pattern)
 {
+    if (node->selector_token != pattern->selector_token)
+        return false;
+    if (node->lparen_token != pattern->lparen_token)
+        return false;
+    if (! AST::match(node->selector, pattern->selector, this))
+        return false;
+    if (node->rparen_token != pattern->rparen_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ObjCInstanceVariablesDeclarationAST *, ObjCInstanceVariablesDeclarationAST *)
+bool ASTMatcher::match(ObjCInstanceVariablesDeclarationAST *node, ObjCInstanceVariablesDeclarationAST *pattern)
 {
+    if (node->lbrace_token != pattern->lbrace_token)
+        return false;
+    if (! AST::match(node->instance_variable_list, pattern->instance_variable_list, this))
+        return false;
+    if (node->rbrace_token != pattern->rbrace_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ObjCVisibilityDeclarationAST *, ObjCVisibilityDeclarationAST *)
+bool ASTMatcher::match(ObjCVisibilityDeclarationAST *node, ObjCVisibilityDeclarationAST *pattern)
 {
+    if (node->visibility_token != pattern->visibility_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ObjCPropertyAttributeAST *, ObjCPropertyAttributeAST *)
+bool ASTMatcher::match(ObjCPropertyAttributeAST *node, ObjCPropertyAttributeAST *pattern)
 {
+    if (node->attribute_identifier_token != pattern->attribute_identifier_token)
+        return false;
+    if (node->equals_token != pattern->equals_token)
+        return false;
+    if (! AST::match(node->method_selector, pattern->method_selector, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ObjCPropertyDeclarationAST *, ObjCPropertyDeclarationAST *)
+bool ASTMatcher::match(ObjCPropertyDeclarationAST *node, ObjCPropertyDeclarationAST *pattern)
 {
+    if (! AST::match(node->attribute_list, pattern->attribute_list, this))
+        return false;
+    if (node->property_token != pattern->property_token)
+        return false;
+    if (node->lparen_token != pattern->lparen_token)
+        return false;
+    if (! AST::match(node->property_attribute_list, pattern->property_attribute_list, this))
+        return false;
+    if (node->rparen_token != pattern->rparen_token)
+        return false;
+    if (! AST::match(node->simple_declaration, pattern->simple_declaration, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ObjCMethodPrototypeAST *, ObjCMethodPrototypeAST *)
+bool ASTMatcher::match(ObjCMessageArgumentDeclarationAST *node, ObjCMessageArgumentDeclarationAST *pattern)
 {
+    if (! AST::match(node->type_name, pattern->type_name, this))
+        return false;
+    if (! AST::match(node->attribute_list, pattern->attribute_list, this))
+        return false;
+    if (node->param_name_token != pattern->param_name_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ObjCMethodDeclarationAST *, ObjCMethodDeclarationAST *)
+bool ASTMatcher::match(ObjCMethodPrototypeAST *node, ObjCMethodPrototypeAST *pattern)
 {
+    if (node->method_type_token != pattern->method_type_token)
+        return false;
+    if (! AST::match(node->type_name, pattern->type_name, this))
+        return false;
+    if (! AST::match(node->selector, pattern->selector, this))
+        return false;
+    if (! AST::match(node->argument_list, pattern->argument_list, this))
+        return false;
+    if (node->dot_dot_dot_token != pattern->dot_dot_dot_token)
+        return false;
+    if (! AST::match(node->attribute_list, pattern->attribute_list, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ObjCMessageArgumentDeclarationAST *, ObjCMessageArgumentDeclarationAST *)
+bool ASTMatcher::match(ObjCMethodDeclarationAST *node, ObjCMethodDeclarationAST *pattern)
 {
+    if (! AST::match(node->method_prototype, pattern->method_prototype, this))
+        return false;
+    if (! AST::match(node->function_body, pattern->function_body, this))
+        return false;
+    if (node->semicolon_token != pattern->semicolon_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ObjCSynthesizedPropertyAST *, ObjCSynthesizedPropertyAST *)
+bool ASTMatcher::match(ObjCSynthesizedPropertyAST *node, ObjCSynthesizedPropertyAST *pattern)
 {
+    if (node->equals_token != pattern->equals_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ObjCSynthesizedPropertiesDeclarationAST *, ObjCSynthesizedPropertiesDeclarationAST *)
+bool ASTMatcher::match(ObjCSynthesizedPropertiesDeclarationAST *node, ObjCSynthesizedPropertiesDeclarationAST *pattern)
 {
+    if (node->synthesized_token != pattern->synthesized_token)
+        return false;
+    if (! AST::match(node->property_identifier_list, pattern->property_identifier_list, this))
+        return false;
+    if (node->semicolon_token != pattern->semicolon_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ObjCDynamicPropertiesDeclarationAST *, ObjCDynamicPropertiesDeclarationAST *)
+bool ASTMatcher::match(ObjCDynamicPropertiesDeclarationAST *node, ObjCDynamicPropertiesDeclarationAST *pattern)
 {
+    if (node->dynamic_token != pattern->dynamic_token)
+        return false;
+    if (! AST::match(node->property_identifier_list, pattern->property_identifier_list, this))
+        return false;
+    if (node->semicolon_token != pattern->semicolon_token)
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ObjCFastEnumerationAST *, ObjCFastEnumerationAST *)
+bool ASTMatcher::match(ObjCFastEnumerationAST *node, ObjCFastEnumerationAST *pattern)
 {
+    if (node->for_token != pattern->for_token)
+        return false;
+    if (node->lparen_token != pattern->lparen_token)
+        return false;
+    if (! AST::match(node->type_specifier_list, pattern->type_specifier_list, this))
+        return false;
+    if (! AST::match(node->declarator, pattern->declarator, this))
+        return false;
+    if (! AST::match(node->initializer, pattern->initializer, this))
+        return false;
+    if (node->in_token != pattern->in_token)
+        return false;
+    if (! AST::match(node->fast_enumeratable_expression, pattern->fast_enumeratable_expression, this))
+        return false;
+    if (node->rparen_token != pattern->rparen_token)
+        return false;
+    if (! AST::match(node->body_statement, pattern->body_statement, this))
+        return false;
     return true;
 }
 
-bool ASTMatcher::match(ObjCSynchronizedStatementAST *, ObjCSynchronizedStatementAST *)
+bool ASTMatcher::match(ObjCSynchronizedStatementAST *node, ObjCSynchronizedStatementAST *pattern)
 {
+    if (node->synchronized_token != pattern->synchronized_token)
+        return false;
+    if (node->lparen_token != pattern->lparen_token)
+        return false;
+    if (! AST::match(node->synchronized_object, pattern->synchronized_object, this))
+        return false;
+    if (node->rparen_token != pattern->rparen_token)
+        return false;
+    if (! AST::match(node->statement, pattern->statement, this))
+        return false;
     return true;
 }
+
diff --git a/src/tools/cplusplus/Main.cpp b/src/tools/cplusplus/Main.cpp
index 00fc4eea00a..c1160cb1868 100644
--- a/src/tools/cplusplus/Main.cpp
+++ b/src/tools/cplusplus/Main.cpp
@@ -55,13 +55,13 @@ static const char copyrightHeader[] =
 "**************************************************************************/\n"
 ;
 
-class VisitCG: protected ASTVisitor
+class Accept0CG: protected ASTVisitor
 {
     QDir _cplusplusDir;
     QTextStream *out;
 
 public:
-    VisitCG(const QDir &cplusplusDir, Control *control)
+    Accept0CG(const QDir &cplusplusDir, Control *control)
         : ASTVisitor(control), _cplusplusDir(cplusplusDir), out(0)
     { }
 
@@ -194,13 +194,13 @@ protected:
     }
 };
 
-class MatchCG: protected ASTVisitor
+class Match0CG: protected ASTVisitor
 {
     QDir _cplusplusDir;
     QTextStream *out;
 
 public:
-    MatchCG(const QDir &cplusplusDir, Control *control)
+    Match0CG(const QDir &cplusplusDir, Control *control)
         : ASTVisitor(control), _cplusplusDir(cplusplusDir), out(0)
     { }
 
@@ -245,10 +245,114 @@ protected:
         Overview oo;
         const QString className = oo(klass->name());
 
-        *out << "    if (" << className << " *_other = pattern->as" << className.left(className.length() - 3) << "()) {" << endl;
+        *out << "    if (" << className << " *_other = pattern->as" << className.left(className.length() - 3) << "())" << endl;
 
-        *out << "        if (! matcher->match(this, _other))" << endl
-                << "            return false;" << endl;
+        *out << "        return matcher->match(this, _other);" << endl;
+
+        *out << endl;
+    }
+
+    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;
+    }
+
+    virtual bool visit(ClassSpecifierAST *ast)
+    {
+        Class *klass = ast->symbol;
+        const QByteArray className = id_cast(ast->name);
+
+        Identifier *match0_id = control()->findOrInsertIdentifier("match0");
+        Symbol *accept0Method = klass->members()->lookat(match0_id);
+        for (; accept0Method; accept0Method = accept0Method->next()) {
+            if (accept0Method->identifier() != match0_id)
+                continue;
+
+            if (checkMethod(accept0Method))
+                break;
+        }
+
+        if (! accept0Method)
+            return true;
+
+        classMap.insert(className, ast);
+
+        *out
+                << "bool " << className.constData() << "::match0(AST *pattern, ASTMatcher *matcher)" << endl
+                << "{" << endl;
+
+        visitMembers(klass);
+
+        *out
+                << "    return false;" << endl
+                << "}" << endl
+                << endl;
+
+        return true;
+    }
+};
+
+
+class MatcherCPPCG: protected ASTVisitor
+{
+    QDir _cplusplusDir;
+    QTextStream *out;
+
+public:
+    MatcherCPPCG(const QDir &cplusplusDir, Control *control)
+        : ASTVisitor(control), _cplusplusDir(cplusplusDir), out(0)
+    { }
+
+    void operator()(AST *ast)
+    {
+        QFileInfo fileInfo(_cplusplusDir, QLatin1String("ASTMatcher.cpp"));
+
+        QFile file(fileInfo.absoluteFilePath());
+        if (! file.open(QFile::WriteOnly))
+            return;
+
+        QTextStream output(&file);
+        out = &output;
+
+        *out << copyrightHeader <<
+            "\n"
+            "#include \"AST.h\"\n"
+            "#include \"ASTMatcher.h\"\n"
+            "\n"
+            "using namespace CPlusPlus;\n" << endl;
+
+        accept(ast);
+    }
+
+protected:
+    using ASTVisitor::visit;
+
+    QMap<QByteArray, ClassSpecifierAST *> classMap;
+
+    QByteArray id_cast(NameAST *name)
+    {
+        if (! name)
+            return QByteArray();
+
+        Identifier *id = identifier(name->asSimpleName()->identifier_token);
+
+        return QByteArray::fromRawData(id->chars(), id->size());
+    }
+
+    void visitMembers(Class *klass)
+    {
+        const QByteArray className = klass->name()->identifier()->chars();
 
         for (unsigned i = 0; i < klass->memberCount(); ++i) {
             Symbol *member = klass->memberAt(i);
@@ -262,7 +366,10 @@ protected:
 
             const QByteArray memberName = QByteArray::fromRawData(id->chars(), id->size());
             if (member->type().isUnsigned() && memberName.endsWith("_token")) {
-                // nothing to do here.
+                // nothing to do. The member is a token.
+
+                *out << "    if (node->" << memberName << " != pattern->" << memberName << ")" << endl
+                        << "        return false;" << endl;
 
             } else if (PointerType *ptrTy = member->type()->asPointerType()) {
 
@@ -270,9 +377,8 @@ protected:
                     QByteArray typeName = namedTy->name()->identifier()->chars();
 
                     if (typeName.endsWith("AST")) {
-                        *out << "        if (! match(" << memberName << ", _other->" << memberName << ", matcher))" << endl
-                                << "            return false;" << endl;
-
+                        *out << "    if (! AST::match(node->" << memberName << ", pattern->" << memberName << ", this))" << endl
+                                << "        return false;" << endl;
                     }
                 }
             }
@@ -285,9 +391,6 @@ protected:
                 visitMembers(baseClassSpec->symbol);
             }
         }
-
-        *out << "        return true;" << endl;
-        *out << "    }" << endl;
     }
 
     bool checkMethod(Symbol *accept0Method) const
@@ -312,28 +415,28 @@ protected:
         const QByteArray className = id_cast(ast->name);
 
         Identifier *match0_id = control()->findOrInsertIdentifier("match0");
-        Symbol *accept0Method = klass->members()->lookat(match0_id);
-        for (; accept0Method; accept0Method = accept0Method->next()) {
-            if (accept0Method->identifier() != match0_id)
+        Symbol *match0Method = klass->members()->lookat(match0_id);
+        for (; match0Method; match0Method = match0Method->next()) {
+            if (match0Method->identifier() != match0_id)
                 continue;
 
-            if (checkMethod(accept0Method))
+            if (checkMethod(match0Method))
                 break;
         }
 
-        if (! accept0Method)
+        if (! match0Method)
             return true;
 
         classMap.insert(className, ast);
 
         *out
-                << "bool " << className.constData() << "::match0(AST *pattern, ASTMatcher *matcher)" << endl
+                << "bool ASTMatcher::match(" << className.constData() << " *node, " << className.constData() << " *pattern)" << endl
                 << "{" << endl;
 
         visitMembers(klass);
 
         *out
-                << "    return false;" << endl
+                << "    return true;" << endl
                 << "}" << endl
                 << endl;
 
@@ -341,6 +444,8 @@ protected:
     }
 };
 
+
+
 QTextCursor createCursor(TranslationUnit *unit, AST *ast, QTextDocument *document)
 {
     unsigned startLine, startColumn, endLine, endColumn;
@@ -545,12 +650,15 @@ QStringList generateAST_H(const Snapshot &snapshot, const QDir &cplusplusDir)
         out << document.toPlainText();
     }
 
-    VisitCG cg(cplusplusDir, doc->control());
+    Accept0CG cg(cplusplusDir, doc->control());
     cg(doc->translationUnit()->ast());
 
-    MatchCG cg2(cplusplusDir, doc->control());
+    Match0CG cg2(cplusplusDir, doc->control());
     cg2(doc->translationUnit()->ast());
 
+    MatcherCPPCG cg3(cplusplusDir, doc->control());
+    cg3(doc->translationUnit()->ast());
+
     return astDerivedClasses;
 }
 
-- 
GitLab