From 5644775d2f9a275b6bc0b8081cdb26e8fca29e16 Mon Sep 17 00:00:00 2001
From: Roberto Raggi <roberto.raggi@nokia.com>
Date: Fri, 13 Nov 2009 11:54:22 +0100
Subject: [PATCH] Also match the identifiers and the token types.

---
 src/shared/cplusplus/ASTMatcher.cpp | 515 ++++++++++++++--------------
 src/shared/cplusplus/ASTMatcher.h   |   2 +
 src/tools/cplusplus/Main.cpp        |  15 +-
 3 files changed, 280 insertions(+), 252 deletions(-)

diff --git a/src/shared/cplusplus/ASTMatcher.cpp b/src/shared/cplusplus/ASTMatcher.cpp
index 40fb554175d..5d9269602a3 100644
--- a/src/shared/cplusplus/ASTMatcher.cpp
+++ b/src/shared/cplusplus/ASTMatcher.cpp
@@ -89,54 +89,67 @@ void ASTMatcher::getTokenStartPosition(unsigned index, unsigned *line, unsigned
 void ASTMatcher::getTokenEndPosition(unsigned index, unsigned *line, unsigned *column) const
 { getPosition(tokenAt(index).end(), line, column); }
 
+bool ASTMatcher::matchToken(unsigned index, unsigned otherIndex) const
+{
+    const Token &token = tokenAt(index);
+    const Token &otherToken = tokenAt(otherIndex);
+    if (token.f.kind != otherToken.f.kind)
+        return false;
+    else if (token.is(T_IDENTIFIER)) {
+        if (token.identifier != otherToken.identifier)
+            return false;
+    }
+    return true;
+}
+
 bool ASTMatcher::match(SimpleSpecifierAST *node, SimpleSpecifierAST *pattern)
 {
-    if (node->specifier_token != pattern->specifier_token)
+    if (! matchToken(node->specifier_token, pattern->specifier_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(AttributeSpecifierAST *node, AttributeSpecifierAST *pattern)
 {
-    if (node->attribute_token != pattern->attribute_token)
+    if (! matchToken(node->attribute_token, pattern->attribute_token))
         return false;
-    if (node->first_lparen_token != pattern->first_lparen_token)
+    if (! matchToken(node->first_lparen_token, pattern->first_lparen_token))
         return false;
-    if (node->second_lparen_token != pattern->second_lparen_token)
+    if (! matchToken(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)
+    if (! matchToken(node->first_rparen_token, pattern->first_rparen_token))
         return false;
-    if (node->second_rparen_token != pattern->second_rparen_token)
+    if (! matchToken(node->second_rparen_token, pattern->second_rparen_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(AttributeAST *node, AttributeAST *pattern)
 {
-    if (node->identifier_token != pattern->identifier_token)
+    if (! matchToken(node->identifier_token, pattern->identifier_token))
         return false;
-    if (node->lparen_token != pattern->lparen_token)
+    if (! matchToken(node->lparen_token, pattern->lparen_token))
         return false;
-    if (node->tag_token != pattern->tag_token)
+    if (! matchToken(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)
+    if (! matchToken(node->rparen_token, pattern->rparen_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(TypeofSpecifierAST *node, TypeofSpecifierAST *pattern)
 {
-    if (node->typeof_token != pattern->typeof_token)
+    if (! matchToken(node->typeof_token, pattern->typeof_token))
         return false;
-    if (node->lparen_token != pattern->lparen_token)
+    if (! matchToken(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)
+    if (! matchToken(node->rparen_token, pattern->rparen_token))
         return false;
     return true;
 }
@@ -153,7 +166,7 @@ bool ASTMatcher::match(DeclaratorAST *node, DeclaratorAST *pattern)
         return false;
     if (! AST::match(node->post_attribute_list, pattern->post_attribute_list, this))
         return false;
-    if (node->equals_token != pattern->equals_token)
+    if (! matchToken(node->equals_token, pattern->equals_token))
         return false;
     if (! AST::match(node->initializer, pattern->initializer, this))
         return false;
@@ -162,55 +175,55 @@ bool ASTMatcher::match(DeclaratorAST *node, DeclaratorAST *pattern)
 
 bool ASTMatcher::match(SimpleDeclarationAST *node, SimpleDeclarationAST *pattern)
 {
-    if (node->qt_invokable_token != pattern->qt_invokable_token)
+    if (! matchToken(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)
+    if (! matchToken(node->semicolon_token, pattern->semicolon_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(EmptyDeclarationAST *node, EmptyDeclarationAST *pattern)
 {
-    if (node->semicolon_token != pattern->semicolon_token)
+    if (! matchToken(node->semicolon_token, pattern->semicolon_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(AccessDeclarationAST *node, AccessDeclarationAST *pattern)
 {
-    if (node->access_specifier_token != pattern->access_specifier_token)
+    if (! matchToken(node->access_specifier_token, pattern->access_specifier_token))
         return false;
-    if (node->slots_token != pattern->slots_token)
+    if (! matchToken(node->slots_token, pattern->slots_token))
         return false;
-    if (node->colon_token != pattern->colon_token)
+    if (! matchToken(node->colon_token, pattern->colon_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(AsmDefinitionAST *node, AsmDefinitionAST *pattern)
 {
-    if (node->asm_token != pattern->asm_token)
+    if (! matchToken(node->asm_token, pattern->asm_token))
         return false;
-    if (node->volatile_token != pattern->volatile_token)
+    if (! matchToken(node->volatile_token, pattern->volatile_token))
         return false;
-    if (node->lparen_token != pattern->lparen_token)
+    if (! matchToken(node->lparen_token, pattern->lparen_token))
         return false;
-    if (node->rparen_token != pattern->rparen_token)
+    if (! matchToken(node->rparen_token, pattern->rparen_token))
         return false;
-    if (node->semicolon_token != pattern->semicolon_token)
+    if (! matchToken(node->semicolon_token, pattern->semicolon_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(BaseSpecifierAST *node, BaseSpecifierAST *pattern)
 {
-    if (node->virtual_token != pattern->virtual_token)
+    if (! matchToken(node->virtual_token, pattern->virtual_token))
         return false;
-    if (node->access_specifier_token != pattern->access_specifier_token)
+    if (! matchToken(node->access_specifier_token, pattern->access_specifier_token))
         return false;
     if (! AST::match(node->name, pattern->name, this))
         return false;
@@ -219,11 +232,11 @@ bool ASTMatcher::match(BaseSpecifierAST *node, BaseSpecifierAST *pattern)
 
 bool ASTMatcher::match(CompoundLiteralAST *node, CompoundLiteralAST *pattern)
 {
-    if (node->lparen_token != pattern->lparen_token)
+    if (! matchToken(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)
+    if (! matchToken(node->rparen_token, pattern->rparen_token))
         return false;
     if (! AST::match(node->initializer, pattern->initializer, this))
         return false;
@@ -232,13 +245,13 @@ bool ASTMatcher::match(CompoundLiteralAST *node, CompoundLiteralAST *pattern)
 
 bool ASTMatcher::match(QtMethodAST *node, QtMethodAST *pattern)
 {
-    if (node->method_token != pattern->method_token)
+    if (! matchToken(node->method_token, pattern->method_token))
         return false;
-    if (node->lparen_token != pattern->lparen_token)
+    if (! matchToken(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)
+    if (! matchToken(node->rparen_token, pattern->rparen_token))
         return false;
     return true;
 }
@@ -247,7 +260,7 @@ 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)
+    if (! matchToken(node->binary_op_token, pattern->binary_op_token))
         return false;
     if (! AST::match(node->right_expression, pattern->right_expression, this))
         return false;
@@ -256,11 +269,11 @@ bool ASTMatcher::match(BinaryExpressionAST *node, BinaryExpressionAST *pattern)
 
 bool ASTMatcher::match(CastExpressionAST *node, CastExpressionAST *pattern)
 {
-    if (node->lparen_token != pattern->lparen_token)
+    if (! matchToken(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)
+    if (! matchToken(node->rparen_token, pattern->rparen_token))
         return false;
     if (! AST::match(node->expression, pattern->expression, this))
         return false;
@@ -269,32 +282,32 @@ bool ASTMatcher::match(CastExpressionAST *node, CastExpressionAST *pattern)
 
 bool ASTMatcher::match(ClassSpecifierAST *node, ClassSpecifierAST *pattern)
 {
-    if (node->classkey_token != pattern->classkey_token)
+    if (! matchToken(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)
+    if (! matchToken(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)
+    if (! matchToken(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)
+    if (! matchToken(node->rbrace_token, pattern->rbrace_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(CaseStatementAST *node, CaseStatementAST *pattern)
 {
-    if (node->case_token != pattern->case_token)
+    if (! matchToken(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)
+    if (! matchToken(node->colon_token, pattern->colon_token))
         return false;
     if (! AST::match(node->statement, pattern->statement, this))
         return false;
@@ -303,11 +316,11 @@ bool ASTMatcher::match(CaseStatementAST *node, CaseStatementAST *pattern)
 
 bool ASTMatcher::match(CompoundStatementAST *node, CompoundStatementAST *pattern)
 {
-    if (node->lbrace_token != pattern->lbrace_token)
+    if (! matchToken(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)
+    if (! matchToken(node->rbrace_token, pattern->rbrace_token))
         return false;
     return true;
 }
@@ -325,11 +338,11 @@ bool ASTMatcher::match(ConditionalExpressionAST *node, ConditionalExpressionAST
 {
     if (! AST::match(node->condition, pattern->condition, this))
         return false;
-    if (node->question_token != pattern->question_token)
+    if (! matchToken(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)
+    if (! matchToken(node->colon_token, pattern->colon_token))
         return false;
     if (! AST::match(node->right_expression, pattern->right_expression, this))
         return false;
@@ -338,26 +351,26 @@ bool ASTMatcher::match(ConditionalExpressionAST *node, ConditionalExpressionAST
 
 bool ASTMatcher::match(CppCastExpressionAST *node, CppCastExpressionAST *pattern)
 {
-    if (node->cast_token != pattern->cast_token)
+    if (! matchToken(node->cast_token, pattern->cast_token))
         return false;
-    if (node->less_token != pattern->less_token)
+    if (! matchToken(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)
+    if (! matchToken(node->greater_token, pattern->greater_token))
         return false;
-    if (node->lparen_token != pattern->lparen_token)
+    if (! matchToken(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)
+    if (! matchToken(node->rparen_token, pattern->rparen_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(CtorInitializerAST *node, CtorInitializerAST *pattern)
 {
-    if (node->colon_token != pattern->colon_token)
+    if (! matchToken(node->colon_token, pattern->colon_token))
         return false;
     if (! AST::match(node->member_initializer_list, pattern->member_initializer_list, this))
         return false;
@@ -380,22 +393,22 @@ bool ASTMatcher::match(DeclaratorIdAST *node, DeclaratorIdAST *pattern)
 
 bool ASTMatcher::match(NestedDeclaratorAST *node, NestedDeclaratorAST *pattern)
 {
-    if (node->lparen_token != pattern->lparen_token)
+    if (! matchToken(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)
+    if (! matchToken(node->rparen_token, pattern->rparen_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(FunctionDeclaratorAST *node, FunctionDeclaratorAST *pattern)
 {
-    if (node->lparen_token != pattern->lparen_token)
+    if (! matchToken(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)
+    if (! matchToken(node->rparen_token, pattern->rparen_token))
         return false;
     if (! AST::match(node->cv_qualifier_list, pattern->cv_qualifier_list, this))
         return false;
@@ -408,24 +421,24 @@ bool ASTMatcher::match(FunctionDeclaratorAST *node, FunctionDeclaratorAST *patte
 
 bool ASTMatcher::match(ArrayDeclaratorAST *node, ArrayDeclaratorAST *pattern)
 {
-    if (node->lbracket_token != pattern->lbracket_token)
+    if (! matchToken(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)
+    if (! matchToken(node->rbracket_token, pattern->rbracket_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(DeleteExpressionAST *node, DeleteExpressionAST *pattern)
 {
-    if (node->scope_token != pattern->scope_token)
+    if (! matchToken(node->scope_token, pattern->scope_token))
         return false;
-    if (node->delete_token != pattern->delete_token)
+    if (! matchToken(node->delete_token, pattern->delete_token))
         return false;
-    if (node->lbracket_token != pattern->lbracket_token)
+    if (! matchToken(node->lbracket_token, pattern->lbracket_token))
         return false;
-    if (node->rbracket_token != pattern->rbracket_token)
+    if (! matchToken(node->rbracket_token, pattern->rbracket_token))
         return false;
     if (! AST::match(node->expression, pattern->expression, this))
         return false;
@@ -434,19 +447,19 @@ bool ASTMatcher::match(DeleteExpressionAST *node, DeleteExpressionAST *pattern)
 
 bool ASTMatcher::match(DoStatementAST *node, DoStatementAST *pattern)
 {
-    if (node->do_token != pattern->do_token)
+    if (! matchToken(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)
+    if (! matchToken(node->while_token, pattern->while_token))
         return false;
-    if (node->lparen_token != pattern->lparen_token)
+    if (! matchToken(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)
+    if (! matchToken(node->rparen_token, pattern->rparen_token))
         return false;
-    if (node->semicolon_token != pattern->semicolon_token)
+    if (! matchToken(node->semicolon_token, pattern->semicolon_token))
         return false;
     return true;
 }
@@ -460,7 +473,7 @@ bool ASTMatcher::match(NamedTypeSpecifierAST *node, NamedTypeSpecifierAST *patte
 
 bool ASTMatcher::match(ElaboratedTypeSpecifierAST *node, ElaboratedTypeSpecifierAST *pattern)
 {
-    if (node->classkey_token != pattern->classkey_token)
+    if (! matchToken(node->classkey_token, pattern->classkey_token))
         return false;
     if (! AST::match(node->name, pattern->name, this))
         return false;
@@ -469,24 +482,24 @@ bool ASTMatcher::match(ElaboratedTypeSpecifierAST *node, ElaboratedTypeSpecifier
 
 bool ASTMatcher::match(EnumSpecifierAST *node, EnumSpecifierAST *pattern)
 {
-    if (node->enum_token != pattern->enum_token)
+    if (! matchToken(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)
+    if (! matchToken(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)
+    if (! matchToken(node->rbrace_token, pattern->rbrace_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(EnumeratorAST *node, EnumeratorAST *pattern)
 {
-    if (node->identifier_token != pattern->identifier_token)
+    if (! matchToken(node->identifier_token, pattern->identifier_token))
         return false;
-    if (node->equal_token != pattern->equal_token)
+    if (! matchToken(node->equal_token, pattern->equal_token))
         return false;
     if (! AST::match(node->expression, pattern->expression, this))
         return false;
@@ -499,22 +512,22 @@ bool ASTMatcher::match(ExceptionDeclarationAST *node, ExceptionDeclarationAST *p
         return false;
     if (! AST::match(node->declarator, pattern->declarator, this))
         return false;
-    if (node->dot_dot_dot_token != pattern->dot_dot_dot_token)
+    if (! matchToken(node->dot_dot_dot_token, pattern->dot_dot_dot_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(ExceptionSpecificationAST *node, ExceptionSpecificationAST *pattern)
 {
-    if (node->throw_token != pattern->throw_token)
+    if (! matchToken(node->throw_token, pattern->throw_token))
         return false;
-    if (node->lparen_token != pattern->lparen_token)
+    if (! matchToken(node->lparen_token, pattern->lparen_token))
         return false;
-    if (node->dot_dot_dot_token != pattern->dot_dot_dot_token)
+    if (! matchToken(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)
+    if (! matchToken(node->rparen_token, pattern->rparen_token))
         return false;
     return true;
 }
@@ -532,14 +545,14 @@ bool ASTMatcher::match(ExpressionStatementAST *node, ExpressionStatementAST *pat
 {
     if (! AST::match(node->expression, pattern->expression, this))
         return false;
-    if (node->semicolon_token != pattern->semicolon_token)
+    if (! matchToken(node->semicolon_token, pattern->semicolon_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(FunctionDefinitionAST *node, FunctionDefinitionAST *pattern)
 {
-    if (node->qt_invokable_token != pattern->qt_invokable_token)
+    if (! matchToken(node->qt_invokable_token, pattern->qt_invokable_token))
         return false;
     if (! AST::match(node->decl_specifier_list, pattern->decl_specifier_list, this))
         return false;
@@ -554,9 +567,9 @@ bool ASTMatcher::match(FunctionDefinitionAST *node, FunctionDefinitionAST *patte
 
 bool ASTMatcher::match(ForeachStatementAST *node, ForeachStatementAST *pattern)
 {
-    if (node->foreach_token != pattern->foreach_token)
+    if (! matchToken(node->foreach_token, pattern->foreach_token))
         return false;
-    if (node->lparen_token != pattern->lparen_token)
+    if (! matchToken(node->lparen_token, pattern->lparen_token))
         return false;
     if (! AST::match(node->type_specifier_list, pattern->type_specifier_list, this))
         return false;
@@ -564,11 +577,11 @@ bool ASTMatcher::match(ForeachStatementAST *node, ForeachStatementAST *pattern)
         return false;
     if (! AST::match(node->initializer, pattern->initializer, this))
         return false;
-    if (node->comma_token != pattern->comma_token)
+    if (! matchToken(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)
+    if (! matchToken(node->rparen_token, pattern->rparen_token))
         return false;
     if (! AST::match(node->statement, pattern->statement, this))
         return false;
@@ -577,19 +590,19 @@ bool ASTMatcher::match(ForeachStatementAST *node, ForeachStatementAST *pattern)
 
 bool ASTMatcher::match(ForStatementAST *node, ForStatementAST *pattern)
 {
-    if (node->for_token != pattern->for_token)
+    if (! matchToken(node->for_token, pattern->for_token))
         return false;
-    if (node->lparen_token != pattern->lparen_token)
+    if (! matchToken(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)
+    if (! matchToken(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)
+    if (! matchToken(node->rparen_token, pattern->rparen_token))
         return false;
     if (! AST::match(node->statement, pattern->statement, this))
         return false;
@@ -598,17 +611,17 @@ bool ASTMatcher::match(ForStatementAST *node, ForStatementAST *pattern)
 
 bool ASTMatcher::match(IfStatementAST *node, IfStatementAST *pattern)
 {
-    if (node->if_token != pattern->if_token)
+    if (! matchToken(node->if_token, pattern->if_token))
         return false;
-    if (node->lparen_token != pattern->lparen_token)
+    if (! matchToken(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)
+    if (! matchToken(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)
+    if (! matchToken(node->else_token, pattern->else_token))
         return false;
     if (! AST::match(node->else_statement, pattern->else_statement, this))
         return false;
@@ -617,20 +630,20 @@ bool ASTMatcher::match(IfStatementAST *node, IfStatementAST *pattern)
 
 bool ASTMatcher::match(ArrayInitializerAST *node, ArrayInitializerAST *pattern)
 {
-    if (node->lbrace_token != pattern->lbrace_token)
+    if (! matchToken(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)
+    if (! matchToken(node->rbrace_token, pattern->rbrace_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(LabeledStatementAST *node, LabeledStatementAST *pattern)
 {
-    if (node->label_token != pattern->label_token)
+    if (! matchToken(node->label_token, pattern->label_token))
         return false;
-    if (node->colon_token != pattern->colon_token)
+    if (! matchToken(node->colon_token, pattern->colon_token))
         return false;
     if (! AST::match(node->statement, pattern->statement, this))
         return false;
@@ -639,20 +652,20 @@ bool ASTMatcher::match(LabeledStatementAST *node, LabeledStatementAST *pattern)
 
 bool ASTMatcher::match(LinkageBodyAST *node, LinkageBodyAST *pattern)
 {
-    if (node->lbrace_token != pattern->lbrace_token)
+    if (! matchToken(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)
+    if (! matchToken(node->rbrace_token, pattern->rbrace_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(LinkageSpecificationAST *node, LinkageSpecificationAST *pattern)
 {
-    if (node->extern_token != pattern->extern_token)
+    if (! matchToken(node->extern_token, pattern->extern_token))
         return false;
-    if (node->extern_type_token != pattern->extern_type_token)
+    if (! matchToken(node->extern_type_token, pattern->extern_type_token))
         return false;
     if (! AST::match(node->declaration, pattern->declaration, this))
         return false;
@@ -663,11 +676,11 @@ bool ASTMatcher::match(MemInitializerAST *node, MemInitializerAST *pattern)
 {
     if (! AST::match(node->name, pattern->name, this))
         return false;
-    if (node->lparen_token != pattern->lparen_token)
+    if (! matchToken(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)
+    if (! matchToken(node->rparen_token, pattern->rparen_token))
         return false;
     return true;
 }
@@ -676,14 +689,14 @@ bool ASTMatcher::match(NestedNameSpecifierAST *node, NestedNameSpecifierAST *pat
 {
     if (! AST::match(node->class_or_namespace_name, pattern->class_or_namespace_name, this))
         return false;
-    if (node->scope_token != pattern->scope_token)
+    if (! matchToken(node->scope_token, pattern->scope_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(QualifiedNameAST *node, QualifiedNameAST *pattern)
 {
-    if (node->global_scope_token != pattern->global_scope_token)
+    if (! matchToken(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;
@@ -694,7 +707,7 @@ bool ASTMatcher::match(QualifiedNameAST *node, QualifiedNameAST *pattern)
 
 bool ASTMatcher::match(OperatorFunctionIdAST *node, OperatorFunctionIdAST *pattern)
 {
-    if (node->operator_token != pattern->operator_token)
+    if (! matchToken(node->operator_token, pattern->operator_token))
         return false;
     if (! AST::match(node->op, pattern->op, this))
         return false;
@@ -703,7 +716,7 @@ bool ASTMatcher::match(OperatorFunctionIdAST *node, OperatorFunctionIdAST *patte
 
 bool ASTMatcher::match(ConversionFunctionIdAST *node, ConversionFunctionIdAST *pattern)
 {
-    if (node->operator_token != pattern->operator_token)
+    if (! matchToken(node->operator_token, pattern->operator_token))
         return false;
     if (! AST::match(node->type_specifier_list, pattern->type_specifier_list, this))
         return false;
@@ -714,38 +727,38 @@ bool ASTMatcher::match(ConversionFunctionIdAST *node, ConversionFunctionIdAST *p
 
 bool ASTMatcher::match(SimpleNameAST *node, SimpleNameAST *pattern)
 {
-    if (node->identifier_token != pattern->identifier_token)
+    if (! matchToken(node->identifier_token, pattern->identifier_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(DestructorNameAST *node, DestructorNameAST *pattern)
 {
-    if (node->tilde_token != pattern->tilde_token)
+    if (! matchToken(node->tilde_token, pattern->tilde_token))
         return false;
-    if (node->identifier_token != pattern->identifier_token)
+    if (! matchToken(node->identifier_token, pattern->identifier_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(TemplateIdAST *node, TemplateIdAST *pattern)
 {
-    if (node->identifier_token != pattern->identifier_token)
+    if (! matchToken(node->identifier_token, pattern->identifier_token))
         return false;
-    if (node->less_token != pattern->less_token)
+    if (! matchToken(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)
+    if (! matchToken(node->greater_token, pattern->greater_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(NamespaceAST *node, NamespaceAST *pattern)
 {
-    if (node->namespace_token != pattern->namespace_token)
+    if (! matchToken(node->namespace_token, pattern->namespace_token))
         return false;
-    if (node->identifier_token != pattern->identifier_token)
+    if (! matchToken(node->identifier_token, pattern->identifier_token))
         return false;
     if (! AST::match(node->attribute_list, pattern->attribute_list, this))
         return false;
@@ -756,54 +769,54 @@ bool ASTMatcher::match(NamespaceAST *node, NamespaceAST *pattern)
 
 bool ASTMatcher::match(NamespaceAliasDefinitionAST *node, NamespaceAliasDefinitionAST *pattern)
 {
-    if (node->namespace_token != pattern->namespace_token)
+    if (! matchToken(node->namespace_token, pattern->namespace_token))
         return false;
-    if (node->namespace_name_token != pattern->namespace_name_token)
+    if (! matchToken(node->namespace_name_token, pattern->namespace_name_token))
         return false;
-    if (node->equal_token != pattern->equal_token)
+    if (! matchToken(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)
+    if (! matchToken(node->semicolon_token, pattern->semicolon_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(NewPlacementAST *node, NewPlacementAST *pattern)
 {
-    if (node->lparen_token != pattern->lparen_token)
+    if (! matchToken(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)
+    if (! matchToken(node->rparen_token, pattern->rparen_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(NewArrayDeclaratorAST *node, NewArrayDeclaratorAST *pattern)
 {
-    if (node->lbracket_token != pattern->lbracket_token)
+    if (! matchToken(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)
+    if (! matchToken(node->rbracket_token, pattern->rbracket_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(NewExpressionAST *node, NewExpressionAST *pattern)
 {
-    if (node->scope_token != pattern->scope_token)
+    if (! matchToken(node->scope_token, pattern->scope_token))
         return false;
-    if (node->new_token != pattern->new_token)
+    if (! matchToken(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)
+    if (! matchToken(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)
+    if (! matchToken(node->rparen_token, pattern->rparen_token))
         return false;
     if (! AST::match(node->new_type_id, pattern->new_type_id, this))
         return false;
@@ -814,11 +827,11 @@ bool ASTMatcher::match(NewExpressionAST *node, NewExpressionAST *pattern)
 
 bool ASTMatcher::match(NewInitializerAST *node, NewInitializerAST *pattern)
 {
-    if (node->lparen_token != pattern->lparen_token)
+    if (! matchToken(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)
+    if (! matchToken(node->rparen_token, pattern->rparen_token))
         return false;
     return true;
 }
@@ -836,11 +849,11 @@ bool ASTMatcher::match(NewTypeIdAST *node, NewTypeIdAST *pattern)
 
 bool ASTMatcher::match(OperatorAST *node, OperatorAST *pattern)
 {
-    if (node->op_token != pattern->op_token)
+    if (! matchToken(node->op_token, pattern->op_token))
         return false;
-    if (node->open_token != pattern->open_token)
+    if (! matchToken(node->open_token, pattern->open_token))
         return false;
-    if (node->close_token != pattern->close_token)
+    if (! matchToken(node->close_token, pattern->close_token))
         return false;
     return true;
 }
@@ -851,7 +864,7 @@ bool ASTMatcher::match(ParameterDeclarationAST *node, ParameterDeclarationAST *p
         return false;
     if (! AST::match(node->declarator, pattern->declarator, this))
         return false;
-    if (node->equal_token != pattern->equal_token)
+    if (! matchToken(node->equal_token, pattern->equal_token))
         return false;
     if (! AST::match(node->expression, pattern->expression, this))
         return false;
@@ -862,45 +875,45 @@ bool ASTMatcher::match(ParameterDeclarationClauseAST *node, ParameterDeclaration
 {
     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)
+    if (! matchToken(node->dot_dot_dot_token, pattern->dot_dot_dot_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(CallAST *node, CallAST *pattern)
 {
-    if (node->lparen_token != pattern->lparen_token)
+    if (! matchToken(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)
+    if (! matchToken(node->rparen_token, pattern->rparen_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(ArrayAccessAST *node, ArrayAccessAST *pattern)
 {
-    if (node->lbracket_token != pattern->lbracket_token)
+    if (! matchToken(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)
+    if (! matchToken(node->rbracket_token, pattern->rbracket_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(PostIncrDecrAST *node, PostIncrDecrAST *pattern)
 {
-    if (node->incr_decr_token != pattern->incr_decr_token)
+    if (! matchToken(node->incr_decr_token, pattern->incr_decr_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(MemberAccessAST *node, MemberAccessAST *pattern)
 {
-    if (node->access_token != pattern->access_token)
+    if (! matchToken(node->access_token, pattern->access_token))
         return false;
-    if (node->template_token != pattern->template_token)
+    if (! matchToken(node->template_token, pattern->template_token))
         return false;
     if (! AST::match(node->member_name, pattern->member_name, this))
         return false;
@@ -909,28 +922,28 @@ bool ASTMatcher::match(MemberAccessAST *node, MemberAccessAST *pattern)
 
 bool ASTMatcher::match(TypeidExpressionAST *node, TypeidExpressionAST *pattern)
 {
-    if (node->typeid_token != pattern->typeid_token)
+    if (! matchToken(node->typeid_token, pattern->typeid_token))
         return false;
-    if (node->lparen_token != pattern->lparen_token)
+    if (! matchToken(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)
+    if (! matchToken(node->rparen_token, pattern->rparen_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(TypenameCallExpressionAST *node, TypenameCallExpressionAST *pattern)
 {
-    if (node->typename_token != pattern->typename_token)
+    if (! matchToken(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)
+    if (! matchToken(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)
+    if (! matchToken(node->rparen_token, pattern->rparen_token))
         return false;
     return true;
 }
@@ -939,11 +952,11 @@ bool ASTMatcher::match(TypeConstructorCallAST *node, TypeConstructorCallAST *pat
 {
     if (! AST::match(node->type_specifier_list, pattern->type_specifier_list, this))
         return false;
-    if (node->lparen_token != pattern->lparen_token)
+    if (! matchToken(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)
+    if (! matchToken(node->rparen_token, pattern->rparen_token))
         return false;
     return true;
 }
@@ -959,11 +972,11 @@ bool ASTMatcher::match(PostfixExpressionAST *node, PostfixExpressionAST *pattern
 
 bool ASTMatcher::match(PointerToMemberAST *node, PointerToMemberAST *pattern)
 {
-    if (node->global_scope_token != pattern->global_scope_token)
+    if (! matchToken(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)
+    if (! matchToken(node->star_token, pattern->star_token))
         return false;
     if (! AST::match(node->cv_qualifier_list, pattern->cv_qualifier_list, this))
         return false;
@@ -972,7 +985,7 @@ bool ASTMatcher::match(PointerToMemberAST *node, PointerToMemberAST *pattern)
 
 bool ASTMatcher::match(PointerAST *node, PointerAST *pattern)
 {
-    if (node->star_token != pattern->star_token)
+    if (! matchToken(node->star_token, pattern->star_token))
         return false;
     if (! AST::match(node->cv_qualifier_list, pattern->cv_qualifier_list, this))
         return false;
@@ -981,99 +994,99 @@ bool ASTMatcher::match(PointerAST *node, PointerAST *pattern)
 
 bool ASTMatcher::match(ReferenceAST *node, ReferenceAST *pattern)
 {
-    if (node->amp_token != pattern->amp_token)
+    if (! matchToken(node->amp_token, pattern->amp_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(BreakStatementAST *node, BreakStatementAST *pattern)
 {
-    if (node->break_token != pattern->break_token)
+    if (! matchToken(node->break_token, pattern->break_token))
         return false;
-    if (node->semicolon_token != pattern->semicolon_token)
+    if (! matchToken(node->semicolon_token, pattern->semicolon_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(ContinueStatementAST *node, ContinueStatementAST *pattern)
 {
-    if (node->continue_token != pattern->continue_token)
+    if (! matchToken(node->continue_token, pattern->continue_token))
         return false;
-    if (node->semicolon_token != pattern->semicolon_token)
+    if (! matchToken(node->semicolon_token, pattern->semicolon_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(GotoStatementAST *node, GotoStatementAST *pattern)
 {
-    if (node->goto_token != pattern->goto_token)
+    if (! matchToken(node->goto_token, pattern->goto_token))
         return false;
-    if (node->identifier_token != pattern->identifier_token)
+    if (! matchToken(node->identifier_token, pattern->identifier_token))
         return false;
-    if (node->semicolon_token != pattern->semicolon_token)
+    if (! matchToken(node->semicolon_token, pattern->semicolon_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(ReturnStatementAST *node, ReturnStatementAST *pattern)
 {
-    if (node->return_token != pattern->return_token)
+    if (! matchToken(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)
+    if (! matchToken(node->semicolon_token, pattern->semicolon_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(SizeofExpressionAST *node, SizeofExpressionAST *pattern)
 {
-    if (node->sizeof_token != pattern->sizeof_token)
+    if (! matchToken(node->sizeof_token, pattern->sizeof_token))
         return false;
-    if (node->lparen_token != pattern->lparen_token)
+    if (! matchToken(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)
+    if (! matchToken(node->rparen_token, pattern->rparen_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(NumericLiteralAST *node, NumericLiteralAST *pattern)
 {
-    if (node->literal_token != pattern->literal_token)
+    if (! matchToken(node->literal_token, pattern->literal_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(BoolLiteralAST *node, BoolLiteralAST *pattern)
 {
-    if (node->literal_token != pattern->literal_token)
+    if (! matchToken(node->literal_token, pattern->literal_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(ThisExpressionAST *node, ThisExpressionAST *pattern)
 {
-    if (node->this_token != pattern->this_token)
+    if (! matchToken(node->this_token, pattern->this_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(NestedExpressionAST *node, NestedExpressionAST *pattern)
 {
-    if (node->lparen_token != pattern->lparen_token)
+    if (! matchToken(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)
+    if (! matchToken(node->rparen_token, pattern->rparen_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(StringLiteralAST *node, StringLiteralAST *pattern)
 {
-    if (node->literal_token != pattern->literal_token)
+    if (! matchToken(node->literal_token, pattern->literal_token))
         return false;
     if (! AST::match(node->next, pattern->next, this))
         return false;
@@ -1082,13 +1095,13 @@ bool ASTMatcher::match(StringLiteralAST *node, StringLiteralAST *pattern)
 
 bool ASTMatcher::match(SwitchStatementAST *node, SwitchStatementAST *pattern)
 {
-    if (node->switch_token != pattern->switch_token)
+    if (! matchToken(node->switch_token, pattern->switch_token))
         return false;
-    if (node->lparen_token != pattern->lparen_token)
+    if (! matchToken(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)
+    if (! matchToken(node->rparen_token, pattern->rparen_token))
         return false;
     if (! AST::match(node->statement, pattern->statement, this))
         return false;
@@ -1097,15 +1110,15 @@ bool ASTMatcher::match(SwitchStatementAST *node, SwitchStatementAST *pattern)
 
 bool ASTMatcher::match(TemplateDeclarationAST *node, TemplateDeclarationAST *pattern)
 {
-    if (node->export_token != pattern->export_token)
+    if (! matchToken(node->export_token, pattern->export_token))
         return false;
-    if (node->template_token != pattern->template_token)
+    if (! matchToken(node->template_token, pattern->template_token))
         return false;
-    if (node->less_token != pattern->less_token)
+    if (! matchToken(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)
+    if (! matchToken(node->greater_token, pattern->greater_token))
         return false;
     if (! AST::match(node->declaration, pattern->declaration, this))
         return false;
@@ -1114,7 +1127,7 @@ bool ASTMatcher::match(TemplateDeclarationAST *node, TemplateDeclarationAST *pat
 
 bool ASTMatcher::match(ThrowExpressionAST *node, ThrowExpressionAST *pattern)
 {
-    if (node->throw_token != pattern->throw_token)
+    if (! matchToken(node->throw_token, pattern->throw_token))
         return false;
     if (! AST::match(node->expression, pattern->expression, this))
         return false;
@@ -1130,7 +1143,7 @@ bool ASTMatcher::match(TranslationUnitAST *node, TranslationUnitAST *pattern)
 
 bool ASTMatcher::match(TryBlockStatementAST *node, TryBlockStatementAST *pattern)
 {
-    if (node->try_token != pattern->try_token)
+    if (! matchToken(node->try_token, pattern->try_token))
         return false;
     if (! AST::match(node->statement, pattern->statement, this))
         return false;
@@ -1141,13 +1154,13 @@ bool ASTMatcher::match(TryBlockStatementAST *node, TryBlockStatementAST *pattern
 
 bool ASTMatcher::match(CatchClauseAST *node, CatchClauseAST *pattern)
 {
-    if (node->catch_token != pattern->catch_token)
+    if (! matchToken(node->catch_token, pattern->catch_token))
         return false;
-    if (node->lparen_token != pattern->lparen_token)
+    if (! matchToken(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)
+    if (! matchToken(node->rparen_token, pattern->rparen_token))
         return false;
     if (! AST::match(node->statement, pattern->statement, this))
         return false;
@@ -1165,11 +1178,11 @@ bool ASTMatcher::match(TypeIdAST *node, TypeIdAST *pattern)
 
 bool ASTMatcher::match(TypenameTypeParameterAST *node, TypenameTypeParameterAST *pattern)
 {
-    if (node->classkey_token != pattern->classkey_token)
+    if (! matchToken(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)
+    if (! matchToken(node->equal_token, pattern->equal_token))
         return false;
     if (! AST::match(node->type_id, pattern->type_id, this))
         return false;
@@ -1178,19 +1191,19 @@ bool ASTMatcher::match(TypenameTypeParameterAST *node, TypenameTypeParameterAST
 
 bool ASTMatcher::match(TemplateTypeParameterAST *node, TemplateTypeParameterAST *pattern)
 {
-    if (node->template_token != pattern->template_token)
+    if (! matchToken(node->template_token, pattern->template_token))
         return false;
-    if (node->less_token != pattern->less_token)
+    if (! matchToken(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)
+    if (! matchToken(node->greater_token, pattern->greater_token))
         return false;
-    if (node->class_token != pattern->class_token)
+    if (! matchToken(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)
+    if (! matchToken(node->equal_token, pattern->equal_token))
         return false;
     if (! AST::match(node->type_id, pattern->type_id, this))
         return false;
@@ -1199,7 +1212,7 @@ bool ASTMatcher::match(TemplateTypeParameterAST *node, TemplateTypeParameterAST
 
 bool ASTMatcher::match(UnaryExpressionAST *node, UnaryExpressionAST *pattern)
 {
-    if (node->unary_op_token != pattern->unary_op_token)
+    if (! matchToken(node->unary_op_token, pattern->unary_op_token))
         return false;
     if (! AST::match(node->expression, pattern->expression, this))
         return false;
@@ -1208,39 +1221,39 @@ bool ASTMatcher::match(UnaryExpressionAST *node, UnaryExpressionAST *pattern)
 
 bool ASTMatcher::match(UsingAST *node, UsingAST *pattern)
 {
-    if (node->using_token != pattern->using_token)
+    if (! matchToken(node->using_token, pattern->using_token))
         return false;
-    if (node->typename_token != pattern->typename_token)
+    if (! matchToken(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)
+    if (! matchToken(node->semicolon_token, pattern->semicolon_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(UsingDirectiveAST *node, UsingDirectiveAST *pattern)
 {
-    if (node->using_token != pattern->using_token)
+    if (! matchToken(node->using_token, pattern->using_token))
         return false;
-    if (node->namespace_token != pattern->namespace_token)
+    if (! matchToken(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)
+    if (! matchToken(node->semicolon_token, pattern->semicolon_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(WhileStatementAST *node, WhileStatementAST *pattern)
 {
-    if (node->while_token != pattern->while_token)
+    if (! matchToken(node->while_token, pattern->while_token))
         return false;
-    if (node->lparen_token != pattern->lparen_token)
+    if (! matchToken(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)
+    if (! matchToken(node->rparen_token, pattern->rparen_token))
         return false;
     if (! AST::match(node->statement, pattern->statement, this))
         return false;
@@ -1251,11 +1264,11 @@ bool ASTMatcher::match(ObjCClassForwardDeclarationAST *node, ObjCClassForwardDec
 {
     if (! AST::match(node->attribute_list, pattern->attribute_list, this))
         return false;
-    if (node->class_token != pattern->class_token)
+    if (! matchToken(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)
+    if (! matchToken(node->semicolon_token, pattern->semicolon_token))
         return false;
     return true;
 }
@@ -1264,19 +1277,19 @@ bool ASTMatcher::match(ObjCClassDeclarationAST *node, ObjCClassDeclarationAST *p
 {
     if (! AST::match(node->attribute_list, pattern->attribute_list, this))
         return false;
-    if (node->interface_token != pattern->interface_token)
+    if (! matchToken(node->interface_token, pattern->interface_token))
         return false;
-    if (node->implementation_token != pattern->implementation_token)
+    if (! matchToken(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)
+    if (! matchToken(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)
+    if (! matchToken(node->rparen_token, pattern->rparen_token))
         return false;
-    if (node->colon_token != pattern->colon_token)
+    if (! matchToken(node->colon_token, pattern->colon_token))
         return false;
     if (! AST::match(node->superclass, pattern->superclass, this))
         return false;
@@ -1286,7 +1299,7 @@ bool ASTMatcher::match(ObjCClassDeclarationAST *node, ObjCClassDeclarationAST *p
         return false;
     if (! AST::match(node->member_declaration_list, pattern->member_declaration_list, this))
         return false;
-    if (node->end_token != pattern->end_token)
+    if (! matchToken(node->end_token, pattern->end_token))
         return false;
     return true;
 }
@@ -1295,11 +1308,11 @@ bool ASTMatcher::match(ObjCProtocolForwardDeclarationAST *node, ObjCProtocolForw
 {
     if (! AST::match(node->attribute_list, pattern->attribute_list, this))
         return false;
-    if (node->protocol_token != pattern->protocol_token)
+    if (! matchToken(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)
+    if (! matchToken(node->semicolon_token, pattern->semicolon_token))
         return false;
     return true;
 }
@@ -1308,7 +1321,7 @@ bool ASTMatcher::match(ObjCProtocolDeclarationAST *node, ObjCProtocolDeclaration
 {
     if (! AST::match(node->attribute_list, pattern->attribute_list, this))
         return false;
-    if (node->protocol_token != pattern->protocol_token)
+    if (! matchToken(node->protocol_token, pattern->protocol_token))
         return false;
     if (! AST::match(node->name, pattern->name, this))
         return false;
@@ -1316,18 +1329,18 @@ bool ASTMatcher::match(ObjCProtocolDeclarationAST *node, ObjCProtocolDeclaration
         return false;
     if (! AST::match(node->member_declaration_list, pattern->member_declaration_list, this))
         return false;
-    if (node->end_token != pattern->end_token)
+    if (! matchToken(node->end_token, pattern->end_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(ObjCProtocolRefsAST *node, ObjCProtocolRefsAST *pattern)
 {
-    if (node->less_token != pattern->less_token)
+    if (! matchToken(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)
+    if (! matchToken(node->greater_token, pattern->greater_token))
         return false;
     return true;
 }
@@ -1341,7 +1354,7 @@ bool ASTMatcher::match(ObjCMessageArgumentAST *node, ObjCMessageArgumentAST *pat
 
 bool ASTMatcher::match(ObjCMessageExpressionAST *node, ObjCMessageExpressionAST *pattern)
 {
-    if (node->lbracket_token != pattern->lbracket_token)
+    if (! matchToken(node->lbracket_token, pattern->lbracket_token))
         return false;
     if (! AST::match(node->receiver_expression, pattern->receiver_expression, this))
         return false;
@@ -1349,38 +1362,38 @@ bool ASTMatcher::match(ObjCMessageExpressionAST *node, ObjCMessageExpressionAST
         return false;
     if (! AST::match(node->argument_list, pattern->argument_list, this))
         return false;
-    if (node->rbracket_token != pattern->rbracket_token)
+    if (! matchToken(node->rbracket_token, pattern->rbracket_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(ObjCProtocolExpressionAST *node, ObjCProtocolExpressionAST *pattern)
 {
-    if (node->protocol_token != pattern->protocol_token)
+    if (! matchToken(node->protocol_token, pattern->protocol_token))
         return false;
-    if (node->lparen_token != pattern->lparen_token)
+    if (! matchToken(node->lparen_token, pattern->lparen_token))
         return false;
-    if (node->identifier_token != pattern->identifier_token)
+    if (! matchToken(node->identifier_token, pattern->identifier_token))
         return false;
-    if (node->rparen_token != pattern->rparen_token)
+    if (! matchToken(node->rparen_token, pattern->rparen_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(ObjCTypeNameAST *node, ObjCTypeNameAST *pattern)
 {
-    if (node->lparen_token != pattern->lparen_token)
+    if (! matchToken(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)
+    if (! matchToken(node->rparen_token, pattern->rparen_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(ObjCEncodeExpressionAST *node, ObjCEncodeExpressionAST *pattern)
 {
-    if (node->encode_token != pattern->encode_token)
+    if (! matchToken(node->encode_token, pattern->encode_token))
         return false;
     if (! AST::match(node->type_name, pattern->type_name, this))
         return false;
@@ -1389,16 +1402,16 @@ bool ASTMatcher::match(ObjCEncodeExpressionAST *node, ObjCEncodeExpressionAST *p
 
 bool ASTMatcher::match(ObjCSelectorWithoutArgumentsAST *node, ObjCSelectorWithoutArgumentsAST *pattern)
 {
-    if (node->name_token != pattern->name_token)
+    if (! matchToken(node->name_token, pattern->name_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(ObjCSelectorArgumentAST *node, ObjCSelectorArgumentAST *pattern)
 {
-    if (node->name_token != pattern->name_token)
+    if (! matchToken(node->name_token, pattern->name_token))
         return false;
-    if (node->colon_token != pattern->colon_token)
+    if (! matchToken(node->colon_token, pattern->colon_token))
         return false;
     return true;
 }
@@ -1412,40 +1425,40 @@ bool ASTMatcher::match(ObjCSelectorWithArgumentsAST *node, ObjCSelectorWithArgum
 
 bool ASTMatcher::match(ObjCSelectorExpressionAST *node, ObjCSelectorExpressionAST *pattern)
 {
-    if (node->selector_token != pattern->selector_token)
+    if (! matchToken(node->selector_token, pattern->selector_token))
         return false;
-    if (node->lparen_token != pattern->lparen_token)
+    if (! matchToken(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)
+    if (! matchToken(node->rparen_token, pattern->rparen_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(ObjCInstanceVariablesDeclarationAST *node, ObjCInstanceVariablesDeclarationAST *pattern)
 {
-    if (node->lbrace_token != pattern->lbrace_token)
+    if (! matchToken(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)
+    if (! matchToken(node->rbrace_token, pattern->rbrace_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(ObjCVisibilityDeclarationAST *node, ObjCVisibilityDeclarationAST *pattern)
 {
-    if (node->visibility_token != pattern->visibility_token)
+    if (! matchToken(node->visibility_token, pattern->visibility_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(ObjCPropertyAttributeAST *node, ObjCPropertyAttributeAST *pattern)
 {
-    if (node->attribute_identifier_token != pattern->attribute_identifier_token)
+    if (! matchToken(node->attribute_identifier_token, pattern->attribute_identifier_token))
         return false;
-    if (node->equals_token != pattern->equals_token)
+    if (! matchToken(node->equals_token, pattern->equals_token))
         return false;
     if (! AST::match(node->method_selector, pattern->method_selector, this))
         return false;
@@ -1456,13 +1469,13 @@ bool ASTMatcher::match(ObjCPropertyDeclarationAST *node, ObjCPropertyDeclaration
 {
     if (! AST::match(node->attribute_list, pattern->attribute_list, this))
         return false;
-    if (node->property_token != pattern->property_token)
+    if (! matchToken(node->property_token, pattern->property_token))
         return false;
-    if (node->lparen_token != pattern->lparen_token)
+    if (! matchToken(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)
+    if (! matchToken(node->rparen_token, pattern->rparen_token))
         return false;
     if (! AST::match(node->simple_declaration, pattern->simple_declaration, this))
         return false;
@@ -1475,14 +1488,14 @@ bool ASTMatcher::match(ObjCMessageArgumentDeclarationAST *node, ObjCMessageArgum
         return false;
     if (! AST::match(node->attribute_list, pattern->attribute_list, this))
         return false;
-    if (node->param_name_token != pattern->param_name_token)
+    if (! matchToken(node->param_name_token, pattern->param_name_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(ObjCMethodPrototypeAST *node, ObjCMethodPrototypeAST *pattern)
 {
-    if (node->method_type_token != pattern->method_type_token)
+    if (! matchToken(node->method_type_token, pattern->method_type_token))
         return false;
     if (! AST::match(node->type_name, pattern->type_name, this))
         return false;
@@ -1490,7 +1503,7 @@ bool ASTMatcher::match(ObjCMethodPrototypeAST *node, ObjCMethodPrototypeAST *pat
         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)
+    if (! matchToken(node->dot_dot_dot_token, pattern->dot_dot_dot_token))
         return false;
     if (! AST::match(node->attribute_list, pattern->attribute_list, this))
         return false;
@@ -1503,45 +1516,45 @@ bool ASTMatcher::match(ObjCMethodDeclarationAST *node, ObjCMethodDeclarationAST
         return false;
     if (! AST::match(node->function_body, pattern->function_body, this))
         return false;
-    if (node->semicolon_token != pattern->semicolon_token)
+    if (! matchToken(node->semicolon_token, pattern->semicolon_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(ObjCSynthesizedPropertyAST *node, ObjCSynthesizedPropertyAST *pattern)
 {
-    if (node->equals_token != pattern->equals_token)
+    if (! matchToken(node->equals_token, pattern->equals_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(ObjCSynthesizedPropertiesDeclarationAST *node, ObjCSynthesizedPropertiesDeclarationAST *pattern)
 {
-    if (node->synthesized_token != pattern->synthesized_token)
+    if (! matchToken(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)
+    if (! matchToken(node->semicolon_token, pattern->semicolon_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(ObjCDynamicPropertiesDeclarationAST *node, ObjCDynamicPropertiesDeclarationAST *pattern)
 {
-    if (node->dynamic_token != pattern->dynamic_token)
+    if (! matchToken(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)
+    if (! matchToken(node->semicolon_token, pattern->semicolon_token))
         return false;
     return true;
 }
 
 bool ASTMatcher::match(ObjCFastEnumerationAST *node, ObjCFastEnumerationAST *pattern)
 {
-    if (node->for_token != pattern->for_token)
+    if (! matchToken(node->for_token, pattern->for_token))
         return false;
-    if (node->lparen_token != pattern->lparen_token)
+    if (! matchToken(node->lparen_token, pattern->lparen_token))
         return false;
     if (! AST::match(node->type_specifier_list, pattern->type_specifier_list, this))
         return false;
@@ -1549,11 +1562,11 @@ bool ASTMatcher::match(ObjCFastEnumerationAST *node, ObjCFastEnumerationAST *pat
         return false;
     if (! AST::match(node->initializer, pattern->initializer, this))
         return false;
-    if (node->in_token != pattern->in_token)
+    if (! matchToken(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)
+    if (! matchToken(node->rparen_token, pattern->rparen_token))
         return false;
     if (! AST::match(node->body_statement, pattern->body_statement, this))
         return false;
@@ -1562,13 +1575,13 @@ bool ASTMatcher::match(ObjCFastEnumerationAST *node, ObjCFastEnumerationAST *pat
 
 bool ASTMatcher::match(ObjCSynchronizedStatementAST *node, ObjCSynchronizedStatementAST *pattern)
 {
-    if (node->synchronized_token != pattern->synchronized_token)
+    if (! matchToken(node->synchronized_token, pattern->synchronized_token))
         return false;
-    if (node->lparen_token != pattern->lparen_token)
+    if (! matchToken(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)
+    if (! matchToken(node->rparen_token, pattern->rparen_token))
         return false;
     if (! AST::match(node->statement, pattern->statement, this))
         return false;
diff --git a/src/shared/cplusplus/ASTMatcher.h b/src/shared/cplusplus/ASTMatcher.h
index 25df0d56463..8bca54baa2f 100644
--- a/src/shared/cplusplus/ASTMatcher.h
+++ b/src/shared/cplusplus/ASTMatcher.h
@@ -65,6 +65,8 @@ public:
 
     void getTokenEndPosition(unsigned index, unsigned *line, unsigned *column) const;
 
+    bool matchToken(unsigned index, unsigned otherIndex) const;
+
     virtual bool match(AccessDeclarationAST *node, AccessDeclarationAST *pattern);
     virtual bool match(ArrayAccessAST *node, ArrayAccessAST *pattern);
     virtual bool match(ArrayDeclaratorAST *node, ArrayDeclaratorAST *pattern);
diff --git a/src/tools/cplusplus/Main.cpp b/src/tools/cplusplus/Main.cpp
index 51694363475..ea2ca82a9de 100644
--- a/src/tools/cplusplus/Main.cpp
+++ b/src/tools/cplusplus/Main.cpp
@@ -387,6 +387,19 @@ public:
                 << endl
                 << "void ASTMatcher::getTokenEndPosition(unsigned index, unsigned *line, unsigned *column) const" << endl
                 << "{ getPosition(tokenAt(index).end(), line, column); }" << endl
+                << endl
+                << "bool ASTMatcher::matchToken(unsigned index, unsigned otherIndex) const" << endl
+                << "{" << endl
+                << "    const Token &token = tokenAt(index);" << endl
+                << "    const Token &otherToken = tokenAt(otherIndex);" << endl
+                << "    if (token.f.kind != otherToken.f.kind)" << endl
+                << "        return false;" << endl
+                << "    else if (token.is(T_IDENTIFIER)) {" << endl
+                << "        if (token.identifier != otherToken.identifier)" << endl
+                << "            return false;" << endl
+                << "    }" << endl
+                << "    return true;" << endl
+                << "}" << endl
                 << endl;
 
         accept(ast);
@@ -425,7 +438,7 @@ protected:
             if (member->type().isUnsigned() && memberName.endsWith("_token")) {
                 // nothing to do. The member is a token.
 
-                *out << "    if (node->" << memberName << " != pattern->" << memberName << ")" << endl
+                *out << "    if (! matchToken(node->" << memberName << ", pattern->" << memberName << "))" << endl
                         << "        return false;" << endl;
 
             } else if (PointerType *ptrTy = member->type()->asPointerType()) {
-- 
GitLab