diff --git a/src/shared/cplusplus/AST.cpp b/src/shared/cplusplus/AST.cpp
index d0ac090099d1195dba22fccac722e2b63789cb24..9ec75bc15a8fb4083e97332cff3f5bad9a98b712 100644
--- a/src/shared/cplusplus/AST.cpp
+++ b/src/shared/cplusplus/AST.cpp
@@ -66,324 +66,6 @@ AST::AST()
 AST::~AST()
 { assert(0); }
 
-AccessDeclarationAST *AST::asAccessDeclaration()
-{ return dynamic_cast<AccessDeclarationAST *>(this); }
-
-ArrayAccessAST *AST::asArrayAccess()
-{ return dynamic_cast<ArrayAccessAST *>(this); }
-
-ArrayDeclaratorAST *AST::asArrayDeclarator()
-{ return dynamic_cast<ArrayDeclaratorAST *>(this); }
-
-ArrayInitializerAST *AST::asArrayInitializer()
-{ return dynamic_cast<ArrayInitializerAST *>(this); }
-
-AsmDefinitionAST *AST::asAsmDefinition()
-{ return dynamic_cast<AsmDefinitionAST *>(this); }
-
-AttributeAST *AST::asAttribute()
-{ return dynamic_cast<AttributeAST *>(this); }
-
-AttributeSpecifierAST *AST::asAttributeSpecifier()
-{ return dynamic_cast<AttributeSpecifierAST *>(this); }
-
-BaseSpecifierAST *AST::asBaseSpecifier()
-{ return dynamic_cast<BaseSpecifierAST *>(this); }
-
-QtMethodAST *AST::asQtMethod()
-{ return dynamic_cast<QtMethodAST *>(this); }
-
-BinaryExpressionAST *AST::asBinaryExpression()
-{ return dynamic_cast<BinaryExpressionAST *>(this); }
-
-BoolLiteralAST *AST::asBoolLiteral()
-{ return dynamic_cast<BoolLiteralAST *>(this); }
-
-BreakStatementAST *AST::asBreakStatement()
-{ return dynamic_cast<BreakStatementAST *>(this); }
-
-CallAST *AST::asCall()
-{ return dynamic_cast<CallAST *>(this); }
-
-CaseStatementAST *AST::asCaseStatement()
-{ return dynamic_cast<CaseStatementAST *>(this); }
-
-CastExpressionAST *AST::asCastExpression()
-{ return dynamic_cast<CastExpressionAST *>(this); }
-
-CatchClauseAST *AST::asCatchClause()
-{ return dynamic_cast<CatchClauseAST *>(this); }
-
-ClassSpecifierAST *AST::asClassSpecifier()
-{ return dynamic_cast<ClassSpecifierAST *>(this); }
-
-CompoundLiteralAST *AST::asCompoundLiteral()
-{ return dynamic_cast<CompoundLiteralAST *>(this); }
-
-CompoundStatementAST *AST::asCompoundStatement()
-{ return dynamic_cast<CompoundStatementAST *>(this); }
-
-ConditionAST *AST::asCondition()
-{ return dynamic_cast<ConditionAST *>(this); }
-
-ConditionalExpressionAST *AST::asConditionalExpression()
-{ return dynamic_cast<ConditionalExpressionAST *>(this); }
-
-ContinueStatementAST *AST::asContinueStatement()
-{ return dynamic_cast<ContinueStatementAST *>(this); }
-
-ConversionFunctionIdAST *AST::asConversionFunctionId()
-{ return dynamic_cast<ConversionFunctionIdAST *>(this); }
-
-CoreDeclaratorAST *AST::asCoreDeclarator()
-{ return dynamic_cast<CoreDeclaratorAST *>(this); }
-
-CppCastExpressionAST *AST::asCppCastExpression()
-{ return dynamic_cast<CppCastExpressionAST *>(this); }
-
-CtorInitializerAST *AST::asCtorInitializer()
-{ return dynamic_cast<CtorInitializerAST *>(this); }
-
-DeclarationAST *AST::asDeclaration()
-{ return dynamic_cast<DeclarationAST *>(this); }
-
-DeclarationStatementAST *AST::asDeclarationStatement()
-{ return dynamic_cast<DeclarationStatementAST *>(this); }
-
-DeclaratorAST *AST::asDeclarator()
-{ return dynamic_cast<DeclaratorAST *>(this); }
-
-DeclaratorIdAST *AST::asDeclaratorId()
-{ return dynamic_cast<DeclaratorIdAST *>(this); }
-
-DeclaratorListAST *AST::asDeclaratorList()
-{ return dynamic_cast<DeclaratorListAST *>(this); }
-
-DeleteExpressionAST *AST::asDeleteExpression()
-{ return dynamic_cast<DeleteExpressionAST *>(this); }
-
-DestructorNameAST *AST::asDestructorName()
-{ return dynamic_cast<DestructorNameAST *>(this); }
-
-DoStatementAST *AST::asDoStatement()
-{ return dynamic_cast<DoStatementAST *>(this); }
-
-ElaboratedTypeSpecifierAST *AST::asElaboratedTypeSpecifier()
-{ return dynamic_cast<ElaboratedTypeSpecifierAST *>(this); }
-
-EmptyDeclarationAST *AST::asEmptyDeclaration()
-{ return dynamic_cast<EmptyDeclarationAST *>(this); }
-
-EnumSpecifierAST *AST::asEnumSpecifier()
-{ return dynamic_cast<EnumSpecifierAST *>(this); }
-
-EnumeratorAST *AST::asEnumerator()
-{ return dynamic_cast<EnumeratorAST *>(this); }
-
-ExceptionDeclarationAST *AST::asExceptionDeclaration()
-{ return dynamic_cast<ExceptionDeclarationAST *>(this); }
-
-ExceptionSpecificationAST *AST::asExceptionSpecification()
-{ return dynamic_cast<ExceptionSpecificationAST *>(this); }
-
-ExpressionAST *AST::asExpression()
-{ return dynamic_cast<ExpressionAST *>(this); }
-
-ExpressionListAST *AST::asExpressionList()
-{ return dynamic_cast<ExpressionListAST *>(this); }
-
-ExpressionOrDeclarationStatementAST *AST::asExpressionOrDeclarationStatement()
-{ return dynamic_cast<ExpressionOrDeclarationStatementAST *>(this); }
-
-ExpressionStatementAST *AST::asExpressionStatement()
-{ return dynamic_cast<ExpressionStatementAST *>(this); }
-
-ForStatementAST *AST::asForStatement()
-{ return dynamic_cast<ForStatementAST *>(this); }
-
-FunctionDeclaratorAST *AST::asFunctionDeclarator()
-{ return dynamic_cast<FunctionDeclaratorAST *>(this); }
-
-FunctionDefinitionAST *AST::asFunctionDefinition()
-{ return dynamic_cast<FunctionDefinitionAST *>(this); }
-
-GotoStatementAST *AST::asGotoStatement()
-{ return dynamic_cast<GotoStatementAST *>(this); }
-
-IfStatementAST *AST::asIfStatement()
-{ return dynamic_cast<IfStatementAST *>(this); }
-
-LabeledStatementAST *AST::asLabeledStatement()
-{ return dynamic_cast<LabeledStatementAST *>(this); }
-
-LinkageBodyAST *AST::asLinkageBody()
-{ return dynamic_cast<LinkageBodyAST *>(this); }
-
-LinkageSpecificationAST *AST::asLinkageSpecification()
-{ return dynamic_cast<LinkageSpecificationAST *>(this); }
-
-MemInitializerAST *AST::asMemInitializer()
-{ return dynamic_cast<MemInitializerAST *>(this); }
-
-MemberAccessAST *AST::asMemberAccess()
-{ return dynamic_cast<MemberAccessAST *>(this); }
-
-NameAST *AST::asName()
-{ return dynamic_cast<NameAST *>(this); }
-
-NamedTypeSpecifierAST *AST::asNamedTypeSpecifier()
-{ return dynamic_cast<NamedTypeSpecifierAST *>(this); }
-
-NamespaceAST *AST::asNamespace()
-{ return dynamic_cast<NamespaceAST *>(this); }
-
-NamespaceAliasDefinitionAST *AST::asNamespaceAliasDefinition()
-{ return dynamic_cast<NamespaceAliasDefinitionAST *>(this); }
-
-NestedDeclaratorAST *AST::asNestedDeclarator()
-{ return dynamic_cast<NestedDeclaratorAST *>(this); }
-
-NestedExpressionAST *AST::asNestedExpression()
-{ return dynamic_cast<NestedExpressionAST *>(this); }
-
-NestedNameSpecifierAST *AST::asNestedNameSpecifier()
-{ return dynamic_cast<NestedNameSpecifierAST *>(this); }
-
-NewDeclaratorAST *AST::asNewDeclarator()
-{ return dynamic_cast<NewDeclaratorAST *>(this); }
-
-NewExpressionAST *AST::asNewExpression()
-{ return dynamic_cast<NewExpressionAST *>(this); }
-
-NewInitializerAST *AST::asNewInitializer()
-{ return dynamic_cast<NewInitializerAST *>(this); }
-
-NewTypeIdAST *AST::asNewTypeId()
-{ return dynamic_cast<NewTypeIdAST *>(this); }
-
-NumericLiteralAST *AST::asNumericLiteral()
-{ return dynamic_cast<NumericLiteralAST *>(this); }
-
-OperatorAST *AST::asOperator()
-{ return dynamic_cast<OperatorAST *>(this); }
-
-OperatorFunctionIdAST *AST::asOperatorFunctionId()
-{ return dynamic_cast<OperatorFunctionIdAST *>(this); }
-
-ParameterDeclarationAST *AST::asParameterDeclaration()
-{ return dynamic_cast<ParameterDeclarationAST *>(this); }
-
-ParameterDeclarationClauseAST *AST::asParameterDeclarationClause()
-{ return dynamic_cast<ParameterDeclarationClauseAST *>(this); }
-
-PointerAST *AST::asPointer()
-{ return dynamic_cast<PointerAST *>(this); }
-
-PointerToMemberAST *AST::asPointerToMember()
-{ return dynamic_cast<PointerToMemberAST *>(this); }
-
-PostIncrDecrAST *AST::asPostIncrDecr()
-{ return dynamic_cast<PostIncrDecrAST *>(this); }
-
-PostfixAST *AST::asPostfix()
-{ return dynamic_cast<PostfixAST *>(this); }
-
-PostfixDeclaratorAST *AST::asPostfixDeclarator()
-{ return dynamic_cast<PostfixDeclaratorAST *>(this); }
-
-PostfixExpressionAST *AST::asPostfixExpression()
-{ return dynamic_cast<PostfixExpressionAST *>(this); }
-
-PtrOperatorAST *AST::asPtrOperator()
-{ return dynamic_cast<PtrOperatorAST *>(this); }
-
-QualifiedNameAST *AST::asQualifiedName()
-{ return dynamic_cast<QualifiedNameAST *>(this); }
-
-ReferenceAST *AST::asReference()
-{ return dynamic_cast<ReferenceAST *>(this); }
-
-ReturnStatementAST *AST::asReturnStatement()
-{ return dynamic_cast<ReturnStatementAST *>(this); }
-
-SimpleDeclarationAST *AST::asSimpleDeclaration()
-{ return dynamic_cast<SimpleDeclarationAST *>(this); }
-
-SimpleNameAST *AST::asSimpleName()
-{ return dynamic_cast<SimpleNameAST *>(this); }
-
-SimpleSpecifierAST *AST::asSimpleSpecifier()
-{ return dynamic_cast<SimpleSpecifierAST *>(this); }
-
-SizeofExpressionAST *AST::asSizeofExpression()
-{ return dynamic_cast<SizeofExpressionAST *>(this); }
-
-SpecifierAST *AST::asSpecifier()
-{ return dynamic_cast<SpecifierAST *>(this); }
-
-StatementAST *AST::asStatement()
-{ return dynamic_cast<StatementAST *>(this); }
-
-StringLiteralAST *AST::asStringLiteral()
-{ return dynamic_cast<StringLiteralAST *>(this); }
-
-SwitchStatementAST *AST::asSwitchStatement()
-{ return dynamic_cast<SwitchStatementAST *>(this); }
-
-TemplateArgumentListAST *AST::asTemplateArgumentList()
-{ return dynamic_cast<TemplateArgumentListAST *>(this); }
-
-TemplateDeclarationAST *AST::asTemplateDeclaration()
-{ return dynamic_cast<TemplateDeclarationAST *>(this); }
-
-TemplateIdAST *AST::asTemplateId()
-{ return dynamic_cast<TemplateIdAST *>(this); }
-
-TemplateTypeParameterAST *AST::asTemplateTypeParameter()
-{ return dynamic_cast<TemplateTypeParameterAST *>(this); }
-
-ThisExpressionAST *AST::asThisExpression()
-{ return dynamic_cast<ThisExpressionAST *>(this); }
-
-ThrowExpressionAST *AST::asThrowExpression()
-{ return dynamic_cast<ThrowExpressionAST *>(this); }
-
-TranslationUnitAST *AST::asTranslationUnit()
-{ return dynamic_cast<TranslationUnitAST *>(this); }
-
-TryBlockStatementAST *AST::asTryBlockStatement()
-{ return dynamic_cast<TryBlockStatementAST *>(this); }
-
-TypeConstructorCallAST *AST::asTypeConstructorCall()
-{ return dynamic_cast<TypeConstructorCallAST *>(this); }
-
-TypeIdAST *AST::asTypeId()
-{ return dynamic_cast<TypeIdAST *>(this); }
-
-TypeidExpressionAST *AST::asTypeidExpression()
-{ return dynamic_cast<TypeidExpressionAST *>(this); }
-
-TypenameCallExpressionAST *AST::asTypenameCallExpression()
-{ return dynamic_cast<TypenameCallExpressionAST *>(this); }
-
-TypenameTypeParameterAST *AST::asTypenameTypeParameter()
-{ return dynamic_cast<TypenameTypeParameterAST *>(this); }
-
-TypeofSpecifierAST *AST::asTypeofSpecifier()
-{ return dynamic_cast<TypeofSpecifierAST *>(this); }
-
-UnaryExpressionAST *AST::asUnaryExpression()
-{ return dynamic_cast<UnaryExpressionAST *>(this); }
-
-UsingAST *AST::asUsing()
-{ return dynamic_cast<UsingAST *>(this); }
-
-UsingDirectiveAST *AST::asUsingDirective()
-{ return dynamic_cast<UsingDirectiveAST *>(this); }
-
-WhileStatementAST *AST::asWhileStatement()
-{ return dynamic_cast<WhileStatementAST *>(this); }
-
 void AST::accept(ASTVisitor *visitor)
 {
     if (visitor->preVisit(this))
@@ -430,6 +112,7 @@ void AttributeSpecifierAST::accept0(ASTVisitor *visitor)
         for (AttributeAST *attr = attributes; attr; attr = attr->next)
             accept(attr, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned AttributeAST::firstToken() const
@@ -478,6 +161,7 @@ void AttributeAST::accept0(ASTVisitor *visitor)
         for (ExpressionListAST *it = expression_list; it; it = it->next)
             accept(it->expression, visitor);
     }
+    visitor->endVisit(this);
 }
 
 AccessDeclarationAST *AccessDeclarationAST::clone(MemoryPool *pool) const
@@ -493,6 +177,7 @@ void AccessDeclarationAST::accept0(ASTVisitor *visitor)
 {
     if (visitor->visit(this)) {
     }
+    visitor->endVisit(this);
 }
 
 unsigned AccessDeclarationAST::firstToken() const
@@ -524,6 +209,7 @@ void ArrayAccessAST::accept0(ASTVisitor *visitor)
     if (visitor->visit(this)) {
         accept(expression, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned ArrayAccessAST::firstToken() const
@@ -555,6 +241,7 @@ void ArrayDeclaratorAST::accept0(ASTVisitor *visitor)
     if (visitor->visit(this)) {
         accept(this->expression, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned ArrayDeclaratorAST::firstToken() const
@@ -587,6 +274,7 @@ void ArrayInitializerAST::accept0(ASTVisitor *visitor)
         for (ExpressionListAST *expr = expression_list; expr; expr = expr->next)
             accept(expr->expression, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned ArrayInitializerAST::firstToken() const
@@ -623,6 +311,7 @@ void AsmDefinitionAST::accept0(ASTVisitor *visitor)
     if (visitor->visit(this)) {
         // ### accept the asm operand list.
     }
+    visitor->endVisit(this);
 }
 
 unsigned AsmDefinitionAST::firstToken() const
@@ -660,6 +349,7 @@ void BaseSpecifierAST::accept0(ASTVisitor *visitor)
     if (visitor->visit(this)) {
         accept(name, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned BaseSpecifierAST::firstToken() const
@@ -713,6 +403,7 @@ void QtMethodAST::accept0(ASTVisitor *visitor)
     if (visitor->visit(this)) {
         accept(declarator, visitor);
     }
+    visitor->endVisit(this);
 }
 
 BinaryExpressionAST *BinaryExpressionAST::clone(MemoryPool *pool) const
@@ -732,6 +423,7 @@ void BinaryExpressionAST::accept0(ASTVisitor *visitor)
         accept(left_expression, visitor);
         accept(right_expression, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned BinaryExpressionAST::firstToken() const
@@ -759,6 +451,7 @@ void BoolLiteralAST::accept0(ASTVisitor *visitor)
 {
     if (visitor->visit(this)) {
     }
+    visitor->endVisit(this);
 }
 
 unsigned BoolLiteralAST::firstToken() const
@@ -789,6 +482,7 @@ void CompoundLiteralAST::accept0(ASTVisitor *visitor)
         accept(type_id, visitor);
         accept(initializer, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned CompoundLiteralAST::firstToken() const
@@ -819,6 +513,7 @@ void BreakStatementAST::accept0(ASTVisitor *visitor)
 {
     if (visitor->visit(this)) {
     }
+    visitor->endVisit(this);
 }
 
 unsigned BreakStatementAST::firstToken() const
@@ -850,6 +545,7 @@ void CallAST::accept0(ASTVisitor *visitor)
                  expr; expr = expr->next)
             accept(expr->expression, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned CallAST::firstToken() const
@@ -884,6 +580,7 @@ void CaseStatementAST::accept0(ASTVisitor *visitor)
 {
     if (visitor->visit(this)) {
     }
+    visitor->endVisit(this);
 }
 
 unsigned CaseStatementAST::firstToken() const
@@ -918,6 +615,7 @@ void CastExpressionAST::accept0(ASTVisitor *visitor)
 {
     if (visitor->visit(this)) {
     }
+    visitor->endVisit(this);
 }
 
 unsigned CastExpressionAST::firstToken() const
@@ -957,6 +655,7 @@ void CatchClauseAST::accept0(ASTVisitor *visitor)
         accept(exception_declaration, visitor);
         accept(statement, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned CatchClauseAST::firstToken() const
@@ -1009,6 +708,7 @@ void ClassSpecifierAST::accept0(ASTVisitor *visitor)
         for (DeclarationAST *decl = member_specifiers; decl; decl = decl->next)
             accept(decl, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned ClassSpecifierAST::firstToken() const
@@ -1064,6 +764,7 @@ void CompoundStatementAST::accept0(ASTVisitor *visitor)
         for (StatementAST *stmt = statements; stmt; stmt = stmt->next)
             accept(stmt, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned CompoundStatementAST::firstToken() const
@@ -1101,6 +802,7 @@ void ConditionAST::accept0(ASTVisitor *visitor)
             accept(spec, visitor);
         accept(declarator, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned ConditionAST::firstToken() const
@@ -1146,6 +848,7 @@ void ConditionalExpressionAST::accept0(ASTVisitor *visitor)
         accept(left_expression, visitor);
         accept(right_expression, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned ConditionalExpressionAST::firstToken() const
@@ -1181,6 +884,7 @@ void ContinueStatementAST::accept0(ASTVisitor *visitor)
 {
     if (visitor->visit(this)) {
     }
+    visitor->endVisit(this);
 }
 
 unsigned ContinueStatementAST::firstToken() const
@@ -1215,6 +919,7 @@ void ConversionFunctionIdAST::accept0(ASTVisitor *visitor)
                  ptr_op = static_cast<PtrOperatorAST *>(ptr_op->next))
             accept(ptr_op, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned ConversionFunctionIdAST::firstToken() const
@@ -1258,6 +963,7 @@ void CppCastExpressionAST::accept0(ASTVisitor *visitor)
         accept(type_id, visitor);
         accept(expression, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned CppCastExpressionAST::firstToken() const
@@ -1298,6 +1004,7 @@ void CtorInitializerAST::accept0(ASTVisitor *visitor)
                  mem_init; mem_init = mem_init->next)
             accept(mem_init, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned CtorInitializerAST::firstToken() const
@@ -1343,6 +1050,7 @@ void DeclaratorAST::accept0(ASTVisitor *visitor)
         accept(attributes, visitor);
         accept(initializer, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned DeclaratorAST::firstToken() const
@@ -1401,6 +1109,7 @@ void DeclarationStatementAST::accept0(ASTVisitor *visitor)
     if (visitor->visit(this)) {
         accept(declaration, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned DeclarationStatementAST::firstToken() const
@@ -1426,6 +1135,7 @@ void DeclaratorIdAST::accept0(ASTVisitor *visitor)
     if (visitor->visit(this)) {
         accept(name, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned DeclaratorIdAST::firstToken() const
@@ -1454,6 +1164,7 @@ void DeclaratorListAST::accept0(ASTVisitor *visitor)
         for (DeclaratorListAST *it = this; it; it = it->next)
             accept(it->declarator, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned DeclaratorListAST::firstToken() const
@@ -1487,6 +1198,7 @@ void DeleteExpressionAST::accept0(ASTVisitor *visitor)
     if (visitor->visit(this)) {
         accept(expression, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned DeleteExpressionAST::firstToken() const
@@ -1521,6 +1233,7 @@ void DestructorNameAST::accept0(ASTVisitor *visitor)
 {
     if (visitor->visit(this)) {
     }
+    visitor->endVisit(this);
 }
 
 unsigned DestructorNameAST::firstToken() const
@@ -1556,6 +1269,7 @@ void DoStatementAST::accept0(ASTVisitor *visitor)
         accept(statement, visitor);
         accept(expression, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned DoStatementAST::firstToken() const
@@ -1594,6 +1308,7 @@ void ElaboratedTypeSpecifierAST::accept0(ASTVisitor *visitor)
     if (visitor->visit(this)) {
         accept(name, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned ElaboratedTypeSpecifierAST::firstToken() const
@@ -1619,6 +1334,7 @@ void EmptyDeclarationAST::accept0(ASTVisitor *visitor)
 {
     if (visitor->visit(this)) {
     }
+    visitor->endVisit(this);
 }
 
 unsigned EmptyDeclarationAST::firstToken() const
@@ -1652,6 +1368,7 @@ void EnumSpecifierAST::accept0(ASTVisitor *visitor)
                  enumerator = enumerator->next)
             accept(enumerator, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned EnumSpecifierAST::firstToken() const
@@ -1694,6 +1411,7 @@ void EnumeratorAST::accept0(ASTVisitor *visitor)
     if (visitor->visit(this)) {
         accept(expression, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned EnumeratorAST::firstToken() const
@@ -1728,6 +1446,7 @@ void ExceptionDeclarationAST::accept0(ASTVisitor *visitor)
             accept(spec, visitor);
         accept(declarator, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned ExceptionDeclarationAST::firstToken() const
@@ -1771,6 +1490,7 @@ void ExceptionSpecificationAST::accept0(ASTVisitor *visitor)
                  type_id = type_id->next)
             accept(type_id->expression, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned ExceptionSpecificationAST::firstToken() const
@@ -1808,9 +1528,12 @@ ExpressionListAST *ExpressionListAST::clone(MemoryPool *pool) const
 
 void ExpressionListAST::accept0(ASTVisitor *visitor)
 {
-    for (const ExpressionListAST *it = this; it; it = it->next) {
-        accept(it->expression, visitor);
+    if (visitor->visit(this)) {
+        for (const ExpressionListAST *it = this; it; it = it->next) {
+            accept(it->expression, visitor);
+        }
     }
+    visitor->endVisit(this);
 }
 
 unsigned ExpressionListAST::firstToken() const
@@ -1843,6 +1566,7 @@ void ExpressionOrDeclarationStatementAST::accept0(ASTVisitor *visitor)
         accept(declaration, visitor);
         accept(expression, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned ExpressionOrDeclarationStatementAST::firstToken() const
@@ -1869,6 +1593,7 @@ void ExpressionStatementAST::accept0(ASTVisitor *visitor)
     if (visitor->visit(this)) {
         accept(expression, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned ExpressionStatementAST::firstToken() const
@@ -1914,6 +1639,7 @@ void ForStatementAST::accept0(ASTVisitor *visitor)
         accept(expression, visitor);
         accept(statement, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned ForStatementAST::firstToken() const
@@ -1959,6 +1685,7 @@ void FunctionDeclaratorAST::accept0(ASTVisitor *visitor)
 {
     if (visitor->visit(this)) {
     }
+    visitor->endVisit(this);
 }
 
 unsigned FunctionDeclaratorAST::firstToken() const
@@ -2008,6 +1735,7 @@ void FunctionDefinitionAST::accept0(ASTVisitor *visitor)
         accept(ctor_initializer, visitor);
         accept(function_body, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned FunctionDefinitionAST::firstToken() const
@@ -2052,6 +1780,7 @@ void GotoStatementAST::accept0(ASTVisitor *visitor)
 {
     if (visitor->visit(this)) {
     }
+    visitor->endVisit(this);
 }
 
 unsigned GotoStatementAST::firstToken() const
@@ -2093,6 +1822,7 @@ void IfStatementAST::accept0(ASTVisitor *visitor)
         accept(statement, visitor);
         accept(else_statement, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned IfStatementAST::firstToken() const
@@ -2132,6 +1862,7 @@ void LabeledStatementAST::accept0(ASTVisitor *visitor)
     if (visitor->visit(this)) {
         accept(statement, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned LabeledStatementAST::firstToken() const
@@ -2165,6 +1896,7 @@ void LinkageBodyAST::accept0(ASTVisitor *visitor)
                  decl = decl->next)
             accept(decl, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned LinkageBodyAST::firstToken() const
@@ -2200,6 +1932,7 @@ void LinkageSpecificationAST::accept0(ASTVisitor *visitor)
     if (visitor->visit(this)) {
         accept(declaration, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned LinkageSpecificationAST::firstToken() const
@@ -2235,6 +1968,7 @@ void MemInitializerAST::accept0(ASTVisitor *visitor)
     if (visitor->visit(this)) {
         accept(expression, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned MemInitializerAST::firstToken() const
@@ -2268,6 +2002,7 @@ void MemberAccessAST::accept0(ASTVisitor *visitor)
     if (visitor->visit(this)) {
         accept(member_name, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned MemberAccessAST::firstToken() const
@@ -2297,6 +2032,7 @@ void NamedTypeSpecifierAST::accept0(ASTVisitor *visitor)
     if (visitor->visit(this)) {
         accept(name, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned NamedTypeSpecifierAST::firstToken() const
@@ -2329,6 +2065,7 @@ void NamespaceAST::accept0(ASTVisitor *visitor)
         }
         accept(linkage_body, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned NamespaceAST::firstToken() const
@@ -2369,6 +2106,7 @@ void NamespaceAliasDefinitionAST::accept0(ASTVisitor *visitor)
     if (visitor->visit(this)) {
         accept(name, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned NamespaceAliasDefinitionAST::firstToken() const
@@ -2404,6 +2142,7 @@ void NestedDeclaratorAST::accept0(ASTVisitor *visitor)
     if (visitor->visit(this)) {
         accept(declarator, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned NestedDeclaratorAST::firstToken() const
@@ -2435,6 +2174,7 @@ void NestedExpressionAST::accept0(ASTVisitor *visitor)
     if (visitor->visit(this)) {
         accept(expression, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned NestedExpressionAST::firstToken() const
@@ -2468,6 +2208,7 @@ void NestedNameSpecifierAST::accept0(ASTVisitor *visitor)
         accept(class_or_namespace_name, visitor);
         accept(next, visitor); // ### I'm not 100% sure about this.
     }
+    visitor->endVisit(this);
 }
 
 unsigned NestedNameSpecifierAST::firstToken() const
@@ -2502,6 +2243,7 @@ void NewDeclaratorAST::accept0(ASTVisitor *visitor)
 
         accept(declarator, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned NewDeclaratorAST::firstToken() const
@@ -2546,6 +2288,7 @@ void NewExpressionAST::accept0(ASTVisitor *visitor)
         accept(new_type_id, visitor);
         accept(new_initializer, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned NewExpressionAST::firstToken() const
@@ -2588,6 +2331,7 @@ void NewInitializerAST::accept0(ASTVisitor *visitor)
     if (visitor->visit(this)) {
         accept(expression, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned NewInitializerAST::firstToken() const
@@ -2634,6 +2378,7 @@ void NewTypeIdAST::accept0(ASTVisitor *visitor)
         accept(new_initializer, visitor);
         accept(new_declarator, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned NewTypeIdAST::firstToken() const
@@ -2667,6 +2412,7 @@ void NumericLiteralAST::accept0(ASTVisitor *visitor)
 {
     if (visitor->visit(this)) {
     }
+    visitor->endVisit(this);
 }
 
 unsigned NumericLiteralAST::firstToken() const
@@ -2692,6 +2438,7 @@ void OperatorAST::accept0(ASTVisitor *visitor)
 {
     if (visitor->visit(this)) {
     }
+    visitor->endVisit(this);
 }
 
 unsigned OperatorAST::firstToken() const
@@ -2722,6 +2469,7 @@ void OperatorFunctionIdAST::accept0(ASTVisitor *visitor)
     if (visitor->visit(this)) {
         accept(op, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned OperatorFunctionIdAST::firstToken() const
@@ -2757,6 +2505,7 @@ void ParameterDeclarationAST::accept0(ASTVisitor *visitor)
         accept(declarator, visitor);
         accept(expression, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned ParameterDeclarationAST::firstToken() const
@@ -2796,6 +2545,7 @@ void ParameterDeclarationClauseAST::accept0(ASTVisitor *visitor)
                 param = param->next)
             accept(param, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned ParameterDeclarationClauseAST::firstToken() const
@@ -2828,6 +2578,7 @@ void PointerAST::accept0(ASTVisitor *visitor)
                  spec = spec->next)
             accept(spec, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned PointerAST::firstToken() const
@@ -2864,6 +2615,7 @@ void PointerToMemberAST::accept0(ASTVisitor *visitor)
                  spec = spec->next)
             accept(spec, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned PointerToMemberAST::firstToken() const
@@ -2907,6 +2659,7 @@ void PostIncrDecrAST::accept0(ASTVisitor *visitor)
 {
     if (visitor->visit(this)) {
     }
+    visitor->endVisit(this);
 }
 
 unsigned PostIncrDecrAST::firstToken() const
@@ -2936,6 +2689,7 @@ void PostfixExpressionAST::accept0(ASTVisitor *visitor)
         for (PostfixAST *fx = postfix_expressions; fx; fx = fx->next)
             accept(fx, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned PostfixExpressionAST::firstToken() const
@@ -2969,6 +2723,7 @@ void QualifiedNameAST::accept0(ASTVisitor *visitor)
         accept(nested_name_specifier, visitor);
         accept(unqualified_name, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned QualifiedNameAST::firstToken() const
@@ -3007,6 +2762,7 @@ void ReferenceAST::accept0(ASTVisitor *visitor)
 {
     if (visitor->visit(this)) {
     }
+    visitor->endVisit(this);
 }
 
 unsigned ReferenceAST::firstToken() const
@@ -3034,6 +2790,7 @@ void ReturnStatementAST::accept0(ASTVisitor *visitor)
     if (visitor->visit(this)) {
         accept(expression, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned ReturnStatementAST::firstToken() const
@@ -3069,6 +2826,7 @@ void SimpleDeclarationAST::accept0(ASTVisitor *visitor)
             accept(spec, visitor);
         accept(declarators, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned SimpleDeclarationAST::firstToken() const
@@ -3109,6 +2867,7 @@ void SimpleNameAST::accept0(ASTVisitor *visitor)
 {
     if (visitor->visit(this)) {
     }
+    visitor->endVisit(this);
 }
 
 unsigned SimpleNameAST::firstToken() const
@@ -3125,6 +2884,7 @@ void SimpleSpecifierAST::accept0(ASTVisitor *visitor)
 {
     if (visitor->visit(this)) {
     }
+    visitor->endVisit(this);
 }
 
 SimpleSpecifierAST *SimpleSpecifierAST::clone(MemoryPool *pool) const
@@ -3162,6 +2922,7 @@ void TypeofSpecifierAST::accept0(ASTVisitor *visitor)
     if (visitor->visit(this)) {
         accept(expression, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned TypeofSpecifierAST::firstToken() const
@@ -3190,6 +2951,7 @@ void SizeofExpressionAST::accept0(ASTVisitor *visitor)
     if (visitor->visit(this)) {
         accept(expression, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned SizeofExpressionAST::firstToken() const
@@ -3218,6 +2980,7 @@ void StringLiteralAST::accept0(ASTVisitor *visitor)
     if (visitor->visit(this)) {
         accept(next, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned StringLiteralAST::firstToken() const
@@ -3251,6 +3014,7 @@ void SwitchStatementAST::accept0(ASTVisitor *visitor)
         accept(condition, visitor);
         accept(statement, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned SwitchStatementAST::firstToken() const
@@ -3287,6 +3051,7 @@ void TemplateArgumentListAST::accept0(ASTVisitor *visitor)
         accept(template_argument, visitor);
         accept(next, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned TemplateArgumentListAST::firstToken() const
@@ -3325,6 +3090,7 @@ void TemplateDeclarationAST::accept0(ASTVisitor *visitor)
             accept(param, visitor);
         accept(declaration, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned TemplateDeclarationAST::firstToken() const
@@ -3374,6 +3140,7 @@ void TemplateIdAST::accept0(ASTVisitor *visitor)
             accept(it, visitor);
         }
     }
+    visitor->endVisit(this);
 }
 
 unsigned TemplateIdAST::firstToken() const
@@ -3418,6 +3185,7 @@ void TemplateTypeParameterAST::accept0(ASTVisitor *visitor)
 {
     if (visitor->visit(this)) {
     }
+    visitor->endVisit(this);
 }
 
 unsigned TemplateTypeParameterAST::firstToken() const
@@ -3460,6 +3228,7 @@ void ThisExpressionAST::accept0(ASTVisitor *visitor)
 {
     if (visitor->visit(this)) {
     }
+    visitor->endVisit(this);
 }
 
 unsigned ThisExpressionAST::firstToken() const
@@ -3486,6 +3255,7 @@ void ThrowExpressionAST::accept0(ASTVisitor *visitor)
     if (visitor->visit(this)) {
         accept(expression, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned ThrowExpressionAST::firstToken() const
@@ -3515,6 +3285,7 @@ void TranslationUnitAST::accept0(ASTVisitor *visitor)
                  decl = decl->next)
             accept(decl, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned TranslationUnitAST::firstToken() const
@@ -3548,6 +3319,7 @@ void TryBlockStatementAST::accept0(ASTVisitor *visitor)
         accept(statement, visitor);
         accept(catch_clause_seq, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned TryBlockStatementAST::firstToken() const
@@ -3589,6 +3361,7 @@ void TypeConstructorCallAST::accept0(ASTVisitor *visitor)
                  expr = expr->next)
             accept(expr->expression, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned TypeConstructorCallAST::firstToken() const
@@ -3625,6 +3398,7 @@ void TypeIdAST::accept0(ASTVisitor *visitor)
             accept(spec, visitor);
         accept(declarator, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned TypeIdAST::firstToken() const
@@ -3661,6 +3435,7 @@ void TypeidExpressionAST::accept0(ASTVisitor *visitor)
     if (visitor->visit(this)) {
         accept(expression, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned TypeidExpressionAST::firstToken() const
@@ -3701,6 +3476,7 @@ void TypenameCallExpressionAST::accept0(ASTVisitor *visitor)
                  expr = expr->next)
             accept(expr->expression, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned TypenameCallExpressionAST::firstToken() const
@@ -3744,6 +3520,7 @@ void TypenameTypeParameterAST::accept0(ASTVisitor *visitor)
         accept(name, visitor);
         accept(type_id, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned TypenameTypeParameterAST::firstToken() const
@@ -3776,6 +3553,7 @@ void UnaryExpressionAST::accept0(ASTVisitor *visitor)
     if (visitor->visit(this)) {
         accept(expression, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned UnaryExpressionAST::firstToken() const
@@ -3806,6 +3584,7 @@ void UsingAST::accept0(ASTVisitor *visitor)
     if (visitor->visit(this)) {
         accept(name, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned UsingAST::firstToken() const
@@ -3840,6 +3619,7 @@ void UsingDirectiveAST::accept0(ASTVisitor *visitor)
     if (visitor->visit(this)) {
         accept(name, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned UsingDirectiveAST::firstToken() const
@@ -3877,6 +3657,7 @@ void WhileStatementAST::accept0(ASTVisitor *visitor)
         accept(condition, visitor);
         accept(statement, visitor);
     }
+    visitor->endVisit(this);
 }
 
 unsigned WhileStatementAST::firstToken() const
@@ -3927,6 +3708,7 @@ void IdentifierListAST::accept0(ASTVisitor *visitor)
 {
     if (visitor->visit(this)) {
     }
+    visitor->endVisit(this);
 }
 
 unsigned ObjCClassDeclarationAST::firstToken() const
@@ -3973,6 +3755,7 @@ void ObjCClassDeclarationAST::accept0(ASTVisitor *visitor)
             accept(it, visitor);
         }
     }
+    visitor->endVisit(this);
 }
 
 
diff --git a/src/shared/cplusplus/AST.h b/src/shared/cplusplus/AST.h
index d29342b30a69ee629ecadc08da930376e65bd83d..26f0a6692b5d04fafe66d80cf813b62883b71f00 100644
--- a/src/shared/cplusplus/AST.h
+++ b/src/shared/cplusplus/AST.h
@@ -91,112 +91,114 @@ public:
     virtual unsigned firstToken() const = 0;
     virtual unsigned lastToken() const = 0;
 
-    AccessDeclarationAST *asAccessDeclaration();
-    ArrayAccessAST *asArrayAccess();
-    ArrayDeclaratorAST *asArrayDeclarator();
-    ArrayInitializerAST *asArrayInitializer();
-    AsmDefinitionAST *asAsmDefinition();
-    AttributeAST *asAttribute();
-    AttributeSpecifierAST *asAttributeSpecifier();
-    BaseSpecifierAST *asBaseSpecifier();
-    QtMethodAST *asQtMethod();
-    BinaryExpressionAST *asBinaryExpression();
-    BoolLiteralAST *asBoolLiteral();
-    BreakStatementAST *asBreakStatement();
-    CallAST *asCall();
-    CaseStatementAST *asCaseStatement();
-    CastExpressionAST *asCastExpression();
-    CatchClauseAST *asCatchClause();
-    ClassSpecifierAST *asClassSpecifier();
-    CompoundLiteralAST *asCompoundLiteral();
-    CompoundStatementAST *asCompoundStatement();
-    ConditionAST *asCondition();
-    ConditionalExpressionAST *asConditionalExpression();
-    ContinueStatementAST *asContinueStatement();
-    ConversionFunctionIdAST *asConversionFunctionId();
-    CoreDeclaratorAST *asCoreDeclarator();
-    CppCastExpressionAST *asCppCastExpression();
-    CtorInitializerAST *asCtorInitializer();
-    DeclarationAST *asDeclaration();
-    DeclarationStatementAST *asDeclarationStatement();
-    DeclaratorAST *asDeclarator();
-    DeclaratorIdAST *asDeclaratorId();
-    DeclaratorListAST *asDeclaratorList();
-    DeleteExpressionAST *asDeleteExpression();
-    DestructorNameAST *asDestructorName();
-    DoStatementAST *asDoStatement();
-    ElaboratedTypeSpecifierAST *asElaboratedTypeSpecifier();
-    EmptyDeclarationAST *asEmptyDeclaration();
-    EnumSpecifierAST *asEnumSpecifier();
-    EnumeratorAST *asEnumerator();
-    ExceptionDeclarationAST *asExceptionDeclaration();
-    ExceptionSpecificationAST *asExceptionSpecification();
-    ExpressionAST *asExpression();
-    ExpressionListAST *asExpressionList();
-    ExpressionOrDeclarationStatementAST *asExpressionOrDeclarationStatement();
-    ExpressionStatementAST *asExpressionStatement();
-    ForStatementAST *asForStatement();
-    FunctionDeclaratorAST *asFunctionDeclarator();
-    FunctionDefinitionAST *asFunctionDefinition();
-    GotoStatementAST *asGotoStatement();
-    IfStatementAST *asIfStatement();
-    LabeledStatementAST *asLabeledStatement();
-    LinkageBodyAST *asLinkageBody();
-    LinkageSpecificationAST *asLinkageSpecification();
-    MemInitializerAST *asMemInitializer();
-    MemberAccessAST *asMemberAccess();
-    NameAST *asName();
-    NamedTypeSpecifierAST *asNamedTypeSpecifier();
-    NamespaceAST *asNamespace();
-    NamespaceAliasDefinitionAST *asNamespaceAliasDefinition();
-    NestedDeclaratorAST *asNestedDeclarator();
-    NestedExpressionAST *asNestedExpression();
-    NestedNameSpecifierAST *asNestedNameSpecifier();
-    NewDeclaratorAST *asNewDeclarator();
-    NewExpressionAST *asNewExpression();
-    NewInitializerAST *asNewInitializer();
-    NewTypeIdAST *asNewTypeId();
-    NumericLiteralAST *asNumericLiteral();
-    OperatorAST *asOperator();
-    OperatorFunctionIdAST *asOperatorFunctionId();
-    ParameterDeclarationAST *asParameterDeclaration();
-    ParameterDeclarationClauseAST *asParameterDeclarationClause();
-    PointerAST *asPointer();
-    PointerToMemberAST *asPointerToMember();
-    PostIncrDecrAST *asPostIncrDecr();
-    PostfixAST *asPostfix();
-    PostfixDeclaratorAST *asPostfixDeclarator();
-    PostfixExpressionAST *asPostfixExpression();
-    PtrOperatorAST *asPtrOperator();
-    QualifiedNameAST *asQualifiedName();
-    ReferenceAST *asReference();
-    ReturnStatementAST *asReturnStatement();
-    SimpleDeclarationAST *asSimpleDeclaration();
-    SimpleNameAST *asSimpleName();
-    SimpleSpecifierAST *asSimpleSpecifier();
-    SizeofExpressionAST *asSizeofExpression();
-    SpecifierAST *asSpecifier();
-    StatementAST *asStatement();
-    StringLiteralAST *asStringLiteral();
-    SwitchStatementAST *asSwitchStatement();
-    TemplateArgumentListAST *asTemplateArgumentList();
-    TemplateDeclarationAST *asTemplateDeclaration();
-    TemplateIdAST *asTemplateId();
-    TemplateTypeParameterAST *asTemplateTypeParameter();
-    ThisExpressionAST *asThisExpression();
-    ThrowExpressionAST *asThrowExpression();
-    TranslationUnitAST *asTranslationUnit();
-    TryBlockStatementAST *asTryBlockStatement();
-    TypeConstructorCallAST *asTypeConstructorCall();
-    TypeIdAST *asTypeId();
-    TypeidExpressionAST *asTypeidExpression();
-    TypenameCallExpressionAST *asTypenameCallExpression();
-    TypenameTypeParameterAST *asTypenameTypeParameter();
-    TypeofSpecifierAST *asTypeofSpecifier();
-    UnaryExpressionAST *asUnaryExpression();
-    UsingAST *asUsing();
-    UsingDirectiveAST *asUsingDirective();
-    WhileStatementAST *asWhileStatement();
+    virtual AccessDeclarationAST *asAccessDeclaration() { return 0; }
+    virtual ArrayAccessAST *asArrayAccess() { return 0; }
+    virtual ArrayDeclaratorAST *asArrayDeclarator() { return 0; }
+    virtual ArrayInitializerAST *asArrayInitializer() { return 0; }
+    virtual AsmDefinitionAST *asAsmDefinition() { return 0; }
+    virtual AttributeAST *asAttribute() { return 0; }
+    virtual AttributeSpecifierAST *asAttributeSpecifier() { return 0; }
+    virtual BaseSpecifierAST *asBaseSpecifier() { return 0; }
+    virtual QtMethodAST *asQtMethod() { return 0; }
+    virtual BinaryExpressionAST *asBinaryExpression() { return 0; }
+    virtual BoolLiteralAST *asBoolLiteral() { return 0; }
+    virtual BreakStatementAST *asBreakStatement() { return 0; }
+    virtual CallAST *asCall() { return 0; }
+    virtual CaseStatementAST *asCaseStatement() { return 0; }
+    virtual CastExpressionAST *asCastExpression() { return 0; }
+    virtual CatchClauseAST *asCatchClause() { return 0; }
+    virtual ClassSpecifierAST *asClassSpecifier() { return 0; }
+    virtual CompoundLiteralAST *asCompoundLiteral() { return 0; }
+    virtual CompoundStatementAST *asCompoundStatement() { return 0; }
+    virtual ConditionAST *asCondition() { return 0; }
+    virtual ConditionalExpressionAST *asConditionalExpression() { return 0; }
+    virtual ContinueStatementAST *asContinueStatement() { return 0; }
+    virtual ConversionFunctionIdAST *asConversionFunctionId() { return 0; }
+    virtual CoreDeclaratorAST *asCoreDeclarator() { return 0; }
+    virtual CppCastExpressionAST *asCppCastExpression() { return 0; }
+    virtual CtorInitializerAST *asCtorInitializer() { return 0; }
+    virtual DeclarationAST *asDeclaration() { return 0; }
+    virtual DeclarationStatementAST *asDeclarationStatement() { return 0; }
+    virtual DeclaratorAST *asDeclarator() { return 0; }
+    virtual DeclaratorIdAST *asDeclaratorId() { return 0; }
+    virtual DeclaratorListAST *asDeclaratorList() { return 0; }
+    virtual DeleteExpressionAST *asDeleteExpression() { return 0; }
+    virtual DestructorNameAST *asDestructorName() { return 0; }
+    virtual DoStatementAST *asDoStatement() { return 0; }
+    virtual ElaboratedTypeSpecifierAST *asElaboratedTypeSpecifier() { return 0; }
+    virtual EmptyDeclarationAST *asEmptyDeclaration() { return 0; }
+    virtual EnumSpecifierAST *asEnumSpecifier() { return 0; }
+    virtual EnumeratorAST *asEnumerator() { return 0; }
+    virtual ExceptionDeclarationAST *asExceptionDeclaration() { return 0; }
+    virtual ExceptionSpecificationAST *asExceptionSpecification() { return 0; }
+    virtual ExpressionAST *asExpression() { return 0; }
+    virtual ExpressionListAST *asExpressionList() { return 0; }
+    virtual ExpressionOrDeclarationStatementAST *asExpressionOrDeclarationStatement() { return 0; }
+    virtual ExpressionStatementAST *asExpressionStatement() { return 0; }
+    virtual ForStatementAST *asForStatement() { return 0; }
+    virtual FunctionDeclaratorAST *asFunctionDeclarator() { return 0; }
+    virtual FunctionDefinitionAST *asFunctionDefinition() { return 0; }
+    virtual GotoStatementAST *asGotoStatement() { return 0; }
+    virtual IfStatementAST *asIfStatement() { return 0; }
+    virtual LabeledStatementAST *asLabeledStatement() { return 0; }
+    virtual LinkageBodyAST *asLinkageBody() { return 0; }
+    virtual LinkageSpecificationAST *asLinkageSpecification() { return 0; }
+    virtual MemInitializerAST *asMemInitializer() { return 0; }
+    virtual MemberAccessAST *asMemberAccess() { return 0; }
+    virtual NameAST *asName() { return 0; }
+    virtual NamedTypeSpecifierAST *asNamedTypeSpecifier() { return 0; }
+    virtual NamespaceAST *asNamespace() { return 0; }
+    virtual NamespaceAliasDefinitionAST *asNamespaceAliasDefinition() { return 0; }
+    virtual NestedDeclaratorAST *asNestedDeclarator() { return 0; }
+    virtual NestedExpressionAST *asNestedExpression() { return 0; }
+    virtual NestedNameSpecifierAST *asNestedNameSpecifier() { return 0; }
+    virtual NewDeclaratorAST *asNewDeclarator() { return 0; }
+    virtual NewExpressionAST *asNewExpression() { return 0; }
+    virtual NewInitializerAST *asNewInitializer() { return 0; }
+    virtual NewTypeIdAST *asNewTypeId() { return 0; }
+    virtual NumericLiteralAST *asNumericLiteral() { return 0; }
+    virtual OperatorAST *asOperator() { return 0; }
+    virtual OperatorFunctionIdAST *asOperatorFunctionId() { return 0; }
+    virtual ParameterDeclarationAST *asParameterDeclaration() { return 0; }
+    virtual ParameterDeclarationClauseAST *asParameterDeclarationClause() { return 0; }
+    virtual PointerAST *asPointer() { return 0; }
+    virtual PointerToMemberAST *asPointerToMember() { return 0; }
+    virtual PostIncrDecrAST *asPostIncrDecr() { return 0; }
+    virtual PostfixAST *asPostfix() { return 0; }
+    virtual PostfixDeclaratorAST *asPostfixDeclarator() { return 0; }
+    virtual PostfixExpressionAST *asPostfixExpression() { return 0; }
+    virtual PtrOperatorAST *asPtrOperator() { return 0; }
+    virtual QualifiedNameAST *asQualifiedName() { return 0; }
+    virtual ReferenceAST *asReference() { return 0; }
+    virtual ReturnStatementAST *asReturnStatement() { return 0; }
+    virtual SimpleDeclarationAST *asSimpleDeclaration() { return 0; }
+    virtual SimpleNameAST *asSimpleName() { return 0; }
+    virtual SimpleSpecifierAST *asSimpleSpecifier() { return 0; }
+    virtual SizeofExpressionAST *asSizeofExpression() { return 0; }
+    virtual SpecifierAST *asSpecifier() { return 0; }
+    virtual StatementAST *asStatement() { return 0; }
+    virtual StringLiteralAST *asStringLiteral() { return 0; }
+    virtual SwitchStatementAST *asSwitchStatement() { return 0; }
+    virtual TemplateArgumentListAST *asTemplateArgumentList() { return 0; }
+    virtual TemplateDeclarationAST *asTemplateDeclaration() { return 0; }
+    virtual TemplateIdAST *asTemplateId() { return 0; }
+    virtual TemplateTypeParameterAST *asTemplateTypeParameter() { return 0; }
+    virtual ThisExpressionAST *asThisExpression() { return 0; }
+    virtual ThrowExpressionAST *asThrowExpression() { return 0; }
+    virtual TranslationUnitAST *asTranslationUnit() { return 0; }
+    virtual TryBlockStatementAST *asTryBlockStatement() { return 0; }
+    virtual TypeConstructorCallAST *asTypeConstructorCall() { return 0; }
+    virtual TypeIdAST *asTypeId() { return 0; }
+    virtual TypeidExpressionAST *asTypeidExpression() { return 0; }
+    virtual TypenameCallExpressionAST *asTypenameCallExpression() { return 0; }
+    virtual TypenameTypeParameterAST *asTypenameTypeParameter() { return 0; }
+    virtual TypeofSpecifierAST *asTypeofSpecifier() { return 0; }
+    virtual UnaryExpressionAST *asUnaryExpression() { return 0; }
+    virtual UsingAST *asUsing() { return 0; }
+    virtual UsingDirectiveAST *asUsingDirective() { return 0; }
+    virtual WhileStatementAST *asWhileStatement() { return 0; }
+    virtual IdentifierListAST *asIdentifierList() { return 0; }
+    virtual ObjCClassDeclarationAST *asObjCClassDeclaration() { return 0; }
 
     virtual AST *clone(MemoryPool *pool) const = 0;
 
@@ -210,6 +212,9 @@ public:
     SpecifierAST *next;
 
 public:
+    virtual SpecifierAST *asSpecifier()
+    { return this; }
+
     virtual SpecifierAST *clone(MemoryPool *pool) const = 0;
 };
 
@@ -219,6 +224,9 @@ public:
     unsigned specifier_token;
 
 public:
+    virtual SimpleSpecifierAST *asSimpleSpecifier()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -239,6 +247,9 @@ public:
     unsigned second_rparen_token;
 
 public:
+    virtual AttributeSpecifierAST *asAttributeSpecifier()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -259,6 +270,9 @@ public:
     AttributeAST *next;
 
 public:
+    virtual AttributeAST *asAttribute()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -275,6 +289,9 @@ public:
     ExpressionAST *expression;
 
 public:
+    virtual TypeofSpecifierAST *asTypeofSpecifier()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -290,12 +307,18 @@ public:
     StatementAST *next;
 
 public:
+    virtual StatementAST *asStatement()
+    { return this; }
+
     virtual StatementAST *clone(MemoryPool *pool) const = 0;
 };
 
 class CPLUSPLUS_EXPORT ExpressionAST: public AST
 {
 public:
+    virtual ExpressionAST *asExpression()
+    { return this; }
+
     virtual ExpressionAST *clone(MemoryPool *pool) const = 0;
 };
 
@@ -305,12 +328,18 @@ public:
     DeclarationAST *next;
 
 public:
+    virtual DeclarationAST *asDeclaration()
+    { return this; }
+
     virtual DeclarationAST *clone(MemoryPool *pool) const = 0;
 };
 
 class CPLUSPLUS_EXPORT CoreDeclaratorAST: public AST
 {
 public:
+    virtual CoreDeclaratorAST *asCoreDeclarator()
+    { return this; }
+
     virtual CoreDeclaratorAST *clone(MemoryPool *pool) const = 0;
 };
 
@@ -320,6 +349,9 @@ public:
     PostfixDeclaratorAST *next;
 
 public:
+    virtual PostfixDeclaratorAST *asPostfixDeclarator()
+    { return this; }
+
     virtual PostfixDeclaratorAST *clone(MemoryPool *pool) const = 0;
 };
 
@@ -333,6 +365,9 @@ public:
     ExpressionAST *initializer;
 
 public:
+    virtual DeclaratorAST *asDeclarator()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -349,6 +384,9 @@ public:
     ExpressionListAST *next;
 
 public:
+    virtual ExpressionListAST *asExpressionList()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -369,6 +407,9 @@ public:
     List<Declaration *> *symbols;
 
 public:
+    virtual SimpleDeclarationAST *asSimpleDeclaration()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -384,6 +425,9 @@ public:
     unsigned semicolon_token;
 
 public:
+    virtual EmptyDeclarationAST *asEmptyDeclaration()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -401,6 +445,9 @@ public:
     unsigned colon_token;
 
 public:
+    virtual AccessDeclarationAST *asAccessDeclaration()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -422,6 +469,9 @@ public:
     unsigned semicolon_token;
 
 public:
+    virtual AsmDefinitionAST *asAsmDefinition()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -443,6 +493,9 @@ public: // annotations
     BaseClass *symbol;
 
 public:
+    virtual BaseSpecifierAST *asBaseSpecifier()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -461,6 +514,9 @@ public:
     ExpressionAST *initializer;
 
 public:
+    virtual CompoundLiteralAST *asCompoundLiteral()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -479,6 +535,9 @@ public:
     unsigned rparen_token;
 
 public:
+    virtual QtMethodAST *asQtMethod()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -496,6 +555,9 @@ public:
     ExpressionAST *right_expression;
 
 public:
+    virtual BinaryExpressionAST *asBinaryExpression()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -514,6 +576,9 @@ public:
     ExpressionAST *expression;
 
 public:
+    virtual CastExpressionAST *asCastExpression()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -539,6 +604,9 @@ public: // annotations
     Class *symbol;
 
 public:
+    virtual ClassSpecifierAST *asClassSpecifier()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -557,6 +625,9 @@ public:
     StatementAST *statement;
 
 public:
+    virtual CaseStatementAST *asCaseStatement()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -573,7 +644,13 @@ public:
     StatementAST *statements;
     unsigned rbrace_token;
 
+public: // annotations
+    Block *symbol;
+
 public:
+    virtual CompoundStatementAST *asCompoundStatement()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -590,6 +667,9 @@ public:
     DeclaratorAST *declarator;
 
 public:
+    virtual ConditionAST *asCondition()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -609,6 +689,9 @@ public:
     ExpressionAST *right_expression;
 
 public:
+    virtual ConditionalExpressionAST *asConditionalExpression()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -630,6 +713,9 @@ public:
     unsigned rparen_token;
 
 public:
+    virtual CppCastExpressionAST *asCppCastExpression()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -646,6 +732,9 @@ public:
     MemInitializerAST *member_initializers;
 
 public:
+    virtual CtorInitializerAST *asCtorInitializer()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -661,6 +750,9 @@ public:
     DeclarationAST *declaration;
 
 public:
+    virtual DeclarationStatementAST *asDeclarationStatement()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -676,6 +768,9 @@ public:
     NameAST *name;
 
 public:
+    virtual DeclaratorIdAST *asDeclaratorId()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -693,6 +788,9 @@ public:
     unsigned rparen_token;
 
 public:
+    virtual NestedDeclaratorAST *asNestedDeclarator()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -715,6 +813,9 @@ public: // annotations
     Function *symbol;
 
 public:
+    virtual FunctionDeclaratorAST *asFunctionDeclarator()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -732,6 +833,9 @@ public:
     unsigned rbracket_token;
 
 public:
+    virtual ArrayDeclaratorAST *asArrayDeclarator()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -748,6 +852,9 @@ public:
     DeclaratorListAST *next;
 
 public:
+    virtual DeclaratorListAST *asDeclaratorList()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -767,6 +874,9 @@ public:
     ExpressionAST *expression;
 
 public:
+    virtual DeleteExpressionAST *asDeleteExpression()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -788,6 +898,9 @@ public:
     unsigned semicolon_token;
 
 public:
+    virtual DoStatementAST *asDoStatement()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -803,6 +916,9 @@ public:
     NameAST *name;
 
 public:
+    virtual NamedTypeSpecifierAST *asNamedTypeSpecifier()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -819,6 +935,9 @@ public:
     NameAST *name;
 
 public:
+    virtual ElaboratedTypeSpecifierAST *asElaboratedTypeSpecifier()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -838,6 +957,9 @@ public:
     unsigned rbrace_token;
 
 public:
+    virtual EnumSpecifierAST *asEnumSpecifier()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -856,6 +978,9 @@ public:
     EnumeratorAST *next;
 
 public:
+    virtual EnumeratorAST *asEnumerator()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -873,6 +998,9 @@ public:
     unsigned dot_dot_dot_token;
 
 public:
+    virtual ExceptionDeclarationAST *asExceptionDeclaration()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -892,6 +1020,9 @@ public:
     unsigned rparen_token;
 
 public:
+    virtual ExceptionSpecificationAST *asExceptionSpecification()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -908,6 +1039,9 @@ public:
     StatementAST *declaration;
 
 public:
+    virtual ExpressionOrDeclarationStatementAST *asExpressionOrDeclarationStatement()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -924,6 +1058,9 @@ public:
     unsigned semicolon_token;
 
 public:
+    virtual ExpressionStatementAST *asExpressionStatement()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -945,6 +1082,9 @@ public: // annotations
     Function *symbol;
 
 public:
+    virtual FunctionDefinitionAST *asFunctionDefinition()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -966,7 +1106,13 @@ public:
     unsigned rparen_token;
     StatementAST *statement;
 
+public: // annotations
+    Block *symbol;
+
 public:
+    virtual ForStatementAST *asForStatement()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -987,7 +1133,13 @@ public:
     unsigned else_token;
     StatementAST *else_statement;
 
+public: // annotations
+    Block *symbol;
+
 public:
+    virtual IfStatementAST *asIfStatement()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1005,6 +1157,9 @@ public:
     unsigned rbrace_token;
 
 public:
+    virtual ArrayInitializerAST *asArrayInitializer()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1022,6 +1177,9 @@ public:
     StatementAST *statement;
 
 public:
+    virtual LabeledStatementAST *asLabeledStatement()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1056,6 +1214,9 @@ public:
     DeclarationAST *declaration;
 
 public:
+    virtual LinkageSpecificationAST *asLinkageSpecification()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1075,6 +1236,9 @@ public:
     MemInitializerAST *next;
 
 public:
+    virtual MemInitializerAST *asMemInitializer()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1101,6 +1265,9 @@ public:
     NestedNameSpecifierAST *next;
 
 public:
+    virtual NestedNameSpecifierAST *asNestedNameSpecifier()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1118,6 +1285,9 @@ public:
     NameAST *unqualified_name;
 
 public:
+    virtual QualifiedNameAST *asQualifiedName()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1134,6 +1304,9 @@ public:
     OperatorAST *op;
 
 public:
+    virtual OperatorFunctionIdAST *asOperatorFunctionId()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1151,6 +1324,9 @@ public:
     PtrOperatorAST *ptr_operators;
 
 public:
+    virtual ConversionFunctionIdAST *asConversionFunctionId()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1166,6 +1342,9 @@ public:
     unsigned identifier_token;
 
 public:
+    virtual SimpleNameAST *asSimpleName()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1182,6 +1361,9 @@ public:
     unsigned identifier_token;
 
 public:
+    virtual DestructorNameAST *asDestructorName()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1200,6 +1382,9 @@ public:
     unsigned greater_token;
 
 public:
+    virtual TemplateIdAST *asTemplateId()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1221,6 +1406,9 @@ public: // annotations
     Namespace *symbol;
 
 public:
+    virtual NamespaceAST *asNamespace()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1240,6 +1428,9 @@ public:
     unsigned semicolon_token;
 
 public:
+    virtual NamespaceAliasDefinitionAST *asNamespaceAliasDefinition()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1256,6 +1447,9 @@ public:
     NewDeclaratorAST *declarator;
 
 public:
+    virtual NewDeclaratorAST *asNewDeclarator()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1276,6 +1470,9 @@ public:
     NewInitializerAST *new_initializer;
 
 public:
+    virtual NewExpressionAST *asNewExpression()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1293,6 +1490,9 @@ public:
     unsigned rparen_token;
 
 public:
+    virtual NewInitializerAST *asNewInitializer()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1310,6 +1510,9 @@ public:
     NewDeclaratorAST *new_declarator;
 
 public:
+    virtual NewTypeIdAST *asNewTypeId()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1327,6 +1530,9 @@ public:
     unsigned close_token;
 
 public:
+    virtual OperatorAST *asOperator()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1348,6 +1554,9 @@ public: // annotations
     Argument *symbol;
 
 public:
+    virtual ParameterDeclarationAST *asParameterDeclaration()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1364,6 +1573,9 @@ public:
     unsigned dot_dot_dot_token;
 
 public:
+    virtual ParameterDeclarationClauseAST *asParameterDeclarationClause()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1379,6 +1591,9 @@ public:
     PostfixAST *next;
 
 public:
+    virtual PostfixAST *asPostfix()
+    { return this; }
+
     virtual PostfixAST *clone(MemoryPool *pool) const = 0;
 };
 
@@ -1390,6 +1605,9 @@ public:
     unsigned rparen_token;
 
 public:
+    virtual CallAST *asCall()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1407,6 +1625,9 @@ public:
     unsigned rbracket_token;
 
 public:
+    virtual ArrayAccessAST *asArrayAccess()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1422,6 +1643,9 @@ public:
     unsigned incr_decr_token;
 
 public:
+    virtual PostIncrDecrAST *asPostIncrDecr()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1439,6 +1663,9 @@ public:
     NameAST *member_name;
 
 public:
+    virtual MemberAccessAST *asMemberAccess()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1457,6 +1684,9 @@ public:
     unsigned rparen_token;
 
 public:
+    virtual TypeidExpressionAST *asTypeidExpression()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1476,6 +1706,9 @@ public:
     unsigned rparen_token;
 
 public:
+    virtual TypenameCallExpressionAST *asTypenameCallExpression()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1494,6 +1727,9 @@ public:
     unsigned rparen_token;
 
 public:
+    virtual TypeConstructorCallAST *asTypeConstructorCall()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1510,6 +1746,9 @@ public:
     PostfixAST *postfix_expressions;
 
 public:
+    virtual PostfixExpressionAST *asPostfixExpression()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1525,6 +1764,9 @@ public:
     PtrOperatorAST *next;
 
 public:
+    virtual PtrOperatorAST *asPtrOperator()
+    { return this; }
+
     virtual PtrOperatorAST *clone(MemoryPool *pool) const = 0;
 };
 
@@ -1537,6 +1779,9 @@ public:
     SpecifierAST *cv_qualifier_seq;
 
 public:
+    virtual PointerToMemberAST *asPointerToMember()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1553,6 +1798,9 @@ public:
     SpecifierAST *cv_qualifier_seq;
 
 public:
+    virtual PointerAST *asPointer()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1568,6 +1816,9 @@ public:
     unsigned amp_token;
 
 public:
+    virtual ReferenceAST *asReference()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1584,6 +1835,9 @@ public:
     unsigned semicolon_token;
 
 public:
+    virtual BreakStatementAST *asBreakStatement()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1600,6 +1854,9 @@ public:
     unsigned semicolon_token;
 
 public:
+    virtual ContinueStatementAST *asContinueStatement()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1617,6 +1874,9 @@ public:
     unsigned semicolon_token;
 
 public:
+    virtual GotoStatementAST *asGotoStatement()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1634,6 +1894,9 @@ public:
     unsigned semicolon_token;
 
 public:
+    virtual ReturnStatementAST *asReturnStatement()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1650,6 +1913,9 @@ public:
     ExpressionAST *expression;
 
 public:
+    virtual SizeofExpressionAST *asSizeofExpression()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1665,6 +1931,9 @@ public:
     unsigned token;
 
 public:
+    virtual NumericLiteralAST *asNumericLiteral()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1680,6 +1949,9 @@ public:
     unsigned token;
 
 public:
+    virtual BoolLiteralAST *asBoolLiteral()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1695,6 +1967,9 @@ public:
     unsigned this_token;
 
 public:
+    virtual ThisExpressionAST *asThisExpression()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1712,6 +1987,9 @@ public:
     unsigned rparen_token;
 
 public:
+    virtual NestedExpressionAST *asNestedExpression()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1728,6 +2006,9 @@ public:
     StringLiteralAST *next;
 
 public:
+    virtual StringLiteralAST *asStringLiteral()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1746,7 +2027,13 @@ public:
     unsigned rparen_token;
     StatementAST *statement;
 
+public: // annotations
+    Block *symbol;
+
 public:
+    virtual SwitchStatementAST *asSwitchStatement()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1763,6 +2050,9 @@ public:
     TemplateArgumentListAST *next;
 
 public:
+    virtual TemplateArgumentListAST *asTemplateArgumentList()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1783,6 +2073,9 @@ public:
     DeclarationAST *declaration;
 
 public:
+    virtual TemplateDeclarationAST *asTemplateDeclaration()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1799,6 +2092,9 @@ public:
     ExpressionAST *expression;
 
 public:
+    virtual ThrowExpressionAST *asThrowExpression()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1814,6 +2110,9 @@ public:
     DeclarationAST *declarations;
 
 public:
+    virtual TranslationUnitAST *asTranslationUnit()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1831,6 +2130,9 @@ public:
     CatchClauseAST *catch_clause_seq;
 
 public:
+    virtual TryBlockStatementAST *asTryBlockStatement()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1850,7 +2152,13 @@ public:
     StatementAST *statement;
     CatchClauseAST *next;
 
+public: // annotations
+    Block *symbol;
+
 public:
+    virtual CatchClauseAST *asCatchClause()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1867,6 +2175,9 @@ public:
     DeclaratorAST *declarator;
 
 public:
+    virtual TypeIdAST *asTypeId()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1888,6 +2199,9 @@ public: // annotations
     Argument *symbol;
 
 public:
+    virtual TypenameTypeParameterAST *asTypenameTypeParameter()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1913,6 +2227,9 @@ public:
     Argument *symbol;
 
 public:
+    virtual TemplateTypeParameterAST *asTemplateTypeParameter()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1929,6 +2246,9 @@ public:
     ExpressionAST *expression;
 
 public:
+    virtual UnaryExpressionAST *asUnaryExpression()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1950,6 +2270,9 @@ public: // annotations
     UsingDeclaration *symbol;
 
 public:
+    virtual UsingAST *asUsing()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1971,6 +2294,9 @@ public:
     UsingNamespaceDirective *symbol;
 
 public:
+    virtual UsingDirectiveAST *asUsingDirective()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -1989,7 +2315,13 @@ public:
     unsigned rparen_token;
     StatementAST *statement;
 
+public: // annotations
+    Block *symbol;
+
 public:
+    virtual WhileStatementAST *asWhileStatement()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -2008,6 +2340,9 @@ public:
     IdentifierListAST *next;
 
 public:
+    virtual IdentifierListAST *asIdentifierList()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
@@ -2026,6 +2361,9 @@ public:
     unsigned semicolon_token;
 
 public:
+    virtual ObjCClassDeclarationAST *asObjCClassDeclaration()
+    { return this; }
+
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
diff --git a/src/shared/cplusplus/ASTVisitor.h b/src/shared/cplusplus/ASTVisitor.h
index f8d2d6790eecbe3bba01a24d1014862696cac596..92fa70e55bdc3a89b7fbd28a72e4604fdcbe4ce9 100644
--- a/src/shared/cplusplus/ASTVisitor.h
+++ b/src/shared/cplusplus/ASTVisitor.h
@@ -190,6 +190,110 @@ public:
     virtual bool visit(IdentifierListAST *) { return true; }
     virtual bool visit(ObjCClassDeclarationAST *) { return true; }
 
+
+
+    virtual void endVisit(AccessDeclarationAST *) { }
+    virtual void endVisit(ArrayAccessAST *) { }
+    virtual void endVisit(ArrayDeclaratorAST *) { }
+    virtual void endVisit(ArrayInitializerAST *) { }
+    virtual void endVisit(AsmDefinitionAST *) { }
+    virtual void endVisit(AttributeSpecifierAST *) { }
+    virtual void endVisit(AttributeAST *) { }
+    virtual void endVisit(BaseSpecifierAST *) { }
+    virtual void endVisit(BinaryExpressionAST *) { }
+    virtual void endVisit(BoolLiteralAST *) { }
+    virtual void endVisit(BreakStatementAST *) { }
+    virtual void endVisit(CallAST *) { }
+    virtual void endVisit(CaseStatementAST *) { }
+    virtual void endVisit(CastExpressionAST *) { }
+    virtual void endVisit(CatchClauseAST *) { }
+    virtual void endVisit(ClassSpecifierAST *) { }
+    virtual void endVisit(CompoundLiteralAST *) { }
+    virtual void endVisit(CompoundStatementAST *) { }
+    virtual void endVisit(ConditionAST *) { }
+    virtual void endVisit(ConditionalExpressionAST *) { }
+    virtual void endVisit(ContinueStatementAST *) { }
+    virtual void endVisit(ConversionFunctionIdAST *) { }
+    virtual void endVisit(CppCastExpressionAST *) { }
+    virtual void endVisit(CtorInitializerAST *) { }
+    virtual void endVisit(DeclaratorAST *) { }
+    virtual void endVisit(DeclarationStatementAST *) { }
+    virtual void endVisit(DeclaratorIdAST *) { }
+    virtual void endVisit(DeclaratorListAST *) { }
+    virtual void endVisit(DeleteExpressionAST *) { }
+    virtual void endVisit(DestructorNameAST *) { }
+    virtual void endVisit(DoStatementAST *) { }
+    virtual void endVisit(ElaboratedTypeSpecifierAST *) { }
+    virtual void endVisit(EmptyDeclarationAST *) { }
+    virtual void endVisit(EnumSpecifierAST *) { }
+    virtual void endVisit(EnumeratorAST *) { }
+    virtual void endVisit(ExceptionDeclarationAST *) { }
+    virtual void endVisit(ExceptionSpecificationAST *) { }
+    virtual void endVisit(ExpressionListAST *) { }
+    virtual void endVisit(ExpressionOrDeclarationStatementAST *) { }
+    virtual void endVisit(ExpressionStatementAST *) { }
+    virtual void endVisit(ForStatementAST *) { }
+    virtual void endVisit(FunctionDeclaratorAST *) { }
+    virtual void endVisit(FunctionDefinitionAST *) { }
+    virtual void endVisit(GotoStatementAST *) { }
+    virtual void endVisit(IfStatementAST *) { }
+    virtual void endVisit(LabeledStatementAST *) { }
+    virtual void endVisit(LinkageBodyAST *) { }
+    virtual void endVisit(LinkageSpecificationAST *) { }
+    virtual void endVisit(MemInitializerAST *) { }
+    virtual void endVisit(MemberAccessAST *) { }
+    virtual void endVisit(NamedTypeSpecifierAST *) { }
+    virtual void endVisit(NamespaceAST *) { }
+    virtual void endVisit(NamespaceAliasDefinitionAST *) { }
+    virtual void endVisit(NestedDeclaratorAST *) { }
+    virtual void endVisit(NestedExpressionAST *) { }
+    virtual void endVisit(NestedNameSpecifierAST *) { }
+    virtual void endVisit(NewDeclaratorAST *) { }
+    virtual void endVisit(NewExpressionAST *) { }
+    virtual void endVisit(NewInitializerAST *) { }
+    virtual void endVisit(NewTypeIdAST *) { }
+    virtual void endVisit(NumericLiteralAST *) { }
+    virtual void endVisit(OperatorAST *) { }
+    virtual void endVisit(OperatorFunctionIdAST *) { }
+    virtual void endVisit(ParameterDeclarationAST *) { }
+    virtual void endVisit(ParameterDeclarationClauseAST *) { }
+    virtual void endVisit(PointerAST *) { }
+    virtual void endVisit(PointerToMemberAST *) { }
+    virtual void endVisit(PostIncrDecrAST *) { }
+    virtual void endVisit(PostfixExpressionAST *) { }
+    virtual void endVisit(QualifiedNameAST *) { }
+    virtual void endVisit(ReferenceAST *) { }
+    virtual void endVisit(ReturnStatementAST *) { }
+    virtual void endVisit(SimpleDeclarationAST *) { }
+    virtual void endVisit(SimpleNameAST *) { }
+    virtual void endVisit(SimpleSpecifierAST *) { }
+    virtual void endVisit(SizeofExpressionAST *) { }
+    virtual void endVisit(StringLiteralAST *) { }
+    virtual void endVisit(SwitchStatementAST *) { }
+    virtual void endVisit(TemplateArgumentListAST *) { }
+    virtual void endVisit(TemplateDeclarationAST *) { }
+    virtual void endVisit(TemplateIdAST *) { }
+    virtual void endVisit(TemplateTypeParameterAST *) { }
+    virtual void endVisit(ThisExpressionAST *) { }
+    virtual void endVisit(ThrowExpressionAST *) { }
+    virtual void endVisit(TranslationUnitAST *) { }
+    virtual void endVisit(TryBlockStatementAST *) { }
+    virtual void endVisit(TypeConstructorCallAST *) { }
+    virtual void endVisit(TypeIdAST *) { }
+    virtual void endVisit(TypeidExpressionAST *) { }
+    virtual void endVisit(TypeofSpecifierAST *) { }
+    virtual void endVisit(TypenameCallExpressionAST *) { }
+    virtual void endVisit(TypenameTypeParameterAST *) { }
+    virtual void endVisit(UnaryExpressionAST *) { }
+    virtual void endVisit(UsingAST *) { }
+    virtual void endVisit(UsingDirectiveAST *) { }
+    virtual void endVisit(WhileStatementAST *) { }
+    virtual void endVisit(QtMethodAST *) { }
+
+    // ObjC++
+    virtual void endVisit(IdentifierListAST *) { }
+    virtual void endVisit(ObjCClassDeclarationAST *) { }
+
 private:
     Control *_control;
 };
diff --git a/src/shared/cplusplus/CheckStatement.cpp b/src/shared/cplusplus/CheckStatement.cpp
index 67902ff252bb3338c50e6e7055ed06ce199d64c7..4c51bc19bd584b23f4384c43bc49b7f1d7ae2741 100644
--- a/src/shared/cplusplus/CheckStatement.cpp
+++ b/src/shared/cplusplus/CheckStatement.cpp
@@ -103,6 +103,7 @@ bool CheckStatement::visit(CaseStatementAST *ast)
 bool CheckStatement::visit(CompoundStatementAST *ast)
 {
     Block *block = control()->newBlock(ast->lbrace_token);
+    ast->symbol = block;
     _scope->enterSymbol(block);
     Scope *previousScope = switchScope(block->members());
     for (StatementAST *it = ast->statements; it; it = it->next) {
@@ -145,6 +146,7 @@ bool CheckStatement::visit(ExpressionStatementAST *ast)
 bool CheckStatement::visit(ForStatementAST *ast)
 {
     Block *block = control()->newBlock(ast->for_token);
+    ast->symbol = block;
     _scope->enterSymbol(block);
     Scope *previousScope = switchScope(block->members());
     semantic()->check(ast->initializer, _scope);
@@ -158,6 +160,7 @@ bool CheckStatement::visit(ForStatementAST *ast)
 bool CheckStatement::visit(IfStatementAST *ast)
 {
     Block *block = control()->newBlock(ast->if_token);
+    ast->symbol = block;
     _scope->enterSymbol(block);
     Scope *previousScope = switchScope(block->members());
     FullySpecifiedType exprTy = semantic()->check(ast->condition, _scope);
@@ -197,6 +200,7 @@ bool CheckStatement::visit(ReturnStatementAST *ast)
 bool CheckStatement::visit(SwitchStatementAST *ast)
 {
     Block *block = control()->newBlock(ast->switch_token);
+    ast->symbol = block;
     _scope->enterSymbol(block);
     Scope *previousScope = switchScope(block->members());
     FullySpecifiedType condTy = semantic()->check(ast->condition, _scope);
@@ -217,6 +221,7 @@ bool CheckStatement::visit(TryBlockStatementAST *ast)
 bool CheckStatement::visit(CatchClauseAST *ast)
 {
     Block *block = control()->newBlock(ast->catch_token);
+    ast->symbol = block;
     _scope->enterSymbol(block);
     Scope *previousScope = switchScope(block->members());
     semantic()->check(ast->exception_declaration, _scope);
@@ -228,6 +233,7 @@ bool CheckStatement::visit(CatchClauseAST *ast)
 bool CheckStatement::visit(WhileStatementAST *ast)
 {
     Block *block = control()->newBlock(ast->while_token);
+    ast->symbol = block;
     _scope->enterSymbol(block);
     Scope *previousScope = switchScope(block->members());
     FullySpecifiedType condTy = semantic()->check(ast->condition, _scope);
diff --git a/src/shared/cplusplus/Name.cpp b/src/shared/cplusplus/Name.cpp
index 89e875a93cb9bc29f245fb805ce1d12aa23a3c56..476a1eff488968f767f57744cd90c9258a8382dc 100644
--- a/src/shared/cplusplus/Name.cpp
+++ b/src/shared/cplusplus/Name.cpp
@@ -63,58 +63,22 @@ Name::~Name()
 { }
 
 bool Name::isNameId() const
-{ return dynamic_cast<const NameId *>(this) != 0; }
+{ return asNameId() != 0; }
 
 bool Name::isTemplateNameId() const
-{ return dynamic_cast<const TemplateNameId *>(this) != 0; }
+{ return asTemplateNameId() != 0; }
 
 bool Name::isDestructorNameId() const
-{ return dynamic_cast<const DestructorNameId *>(this) != 0; }
+{ return asDestructorNameId() != 0; }
 
 bool Name::isOperatorNameId() const
-{ return dynamic_cast<const OperatorNameId *>(this) != 0; }
+{ return asOperatorNameId() != 0; }
 
 bool Name::isConversionNameId() const
-{ return dynamic_cast<const ConversionNameId *>(this) != 0; }
+{ return asConversionNameId() != 0; }
 
 bool Name::isQualifiedNameId() const
-{ return dynamic_cast<const QualifiedNameId *>(this) != 0; }
-
-const NameId *Name::asNameId() const
-{ return dynamic_cast<const NameId *>(this); }
-
-const TemplateNameId *Name::asTemplateNameId() const
-{ return dynamic_cast<const TemplateNameId *>(this); }
-
-const DestructorNameId *Name::asDestructorNameId() const
-{ return dynamic_cast<const DestructorNameId *>(this); }
-
-const OperatorNameId *Name::asOperatorNameId() const
-{ return dynamic_cast<const OperatorNameId *>(this); }
-
-const ConversionNameId *Name::asConversionNameId() const
-{ return dynamic_cast<const ConversionNameId *>(this); }
-
-const QualifiedNameId *Name::asQualifiedNameId() const
-{ return dynamic_cast<const QualifiedNameId *>(this); }
-
-NameId *Name::asNameId()
-{ return dynamic_cast<NameId *>(this); }
-
-TemplateNameId *Name::asTemplateNameId()
-{ return dynamic_cast<TemplateNameId *>(this); }
-
-DestructorNameId *Name::asDestructorNameId()
-{ return dynamic_cast<DestructorNameId *>(this); }
-
-OperatorNameId *Name::asOperatorNameId()
-{ return dynamic_cast<OperatorNameId *>(this); }
-
-ConversionNameId *Name::asConversionNameId()
-{ return dynamic_cast<ConversionNameId *>(this); }
-
-QualifiedNameId *Name::asQualifiedNameId()
-{ return dynamic_cast<QualifiedNameId *>(this); }
+{ return asQualifiedNameId() != 0; }
 
 void Name::accept(NameVisitor *visitor)
 {
diff --git a/src/shared/cplusplus/Name.h b/src/shared/cplusplus/Name.h
index 1f30a28516661d29c72746e6891292f680b60953..6fd73d305f22b74e204a8ec6e9b83107c0f555d6 100644
--- a/src/shared/cplusplus/Name.h
+++ b/src/shared/cplusplus/Name.h
@@ -74,19 +74,19 @@ public:
     bool isConversionNameId() const;
     bool isQualifiedNameId() const;
 
-    const NameId *asNameId() const;
-    const TemplateNameId *asTemplateNameId() const;
-    const DestructorNameId *asDestructorNameId() const;
-    const OperatorNameId *asOperatorNameId() const;
-    const ConversionNameId *asConversionNameId() const;
-    const QualifiedNameId *asQualifiedNameId() const;
+    virtual const NameId *asNameId() const { return 0; }
+    virtual const TemplateNameId *asTemplateNameId() const { return 0; }
+    virtual const DestructorNameId *asDestructorNameId() const { return 0; }
+    virtual const OperatorNameId *asOperatorNameId() const { return 0; }
+    virtual const ConversionNameId *asConversionNameId() const { return 0; }
+    virtual const QualifiedNameId *asQualifiedNameId() const { return 0; }
 
-    NameId *asNameId();
-    TemplateNameId *asTemplateNameId();
-    DestructorNameId *asDestructorNameId();
-    OperatorNameId *asOperatorNameId();
-    ConversionNameId *asConversionNameId();
-    QualifiedNameId *asQualifiedNameId();
+    virtual NameId *asNameId() { return 0; }
+    virtual TemplateNameId *asTemplateNameId() { return 0; }
+    virtual DestructorNameId *asDestructorNameId() { return 0; }
+    virtual OperatorNameId *asOperatorNameId() { return 0; }
+    virtual ConversionNameId *asConversionNameId() { return 0; }
+    virtual QualifiedNameId *asQualifiedNameId() { return 0; }
 
     virtual bool isEqualTo(const Name *other) const = 0;
 
diff --git a/src/shared/cplusplus/Names.h b/src/shared/cplusplus/Names.h
index 86e6813c6c2fd02b70707272f4ca1a658caf8a26..1423c4b96fb36be67ad10c4e44b404dbd685ae93 100644
--- a/src/shared/cplusplus/Names.h
+++ b/src/shared/cplusplus/Names.h
@@ -77,6 +77,12 @@ public:
 
     virtual bool isEqualTo(const Name *other) const;
 
+    virtual const QualifiedNameId *asQualifiedNameId() const
+    { return this; }
+
+    virtual QualifiedNameId *asQualifiedNameId()
+    { return this; }
+
 protected:
     virtual void accept0(NameVisitor *visitor);
 
@@ -96,6 +102,12 @@ public:
 
     virtual bool isEqualTo(const Name *other) const;
 
+    virtual const NameId *asNameId() const
+    { return this; }
+
+    virtual NameId *asNameId()
+    { return this; }
+
 protected:
     virtual void accept0(NameVisitor *visitor);
 
@@ -113,6 +125,12 @@ public:
 
     virtual bool isEqualTo(const Name *other) const;
 
+    virtual const DestructorNameId *asDestructorNameId() const
+    { return this; }
+
+    virtual DestructorNameId *asDestructorNameId()
+    { return this; }
+
 protected:
     virtual void accept0(NameVisitor *visitor);
 
@@ -137,6 +155,12 @@ public:
 
     virtual bool isEqualTo(const Name *other) const;
 
+    virtual const TemplateNameId *asTemplateNameId() const
+    { return this; }
+
+    virtual TemplateNameId *asTemplateNameId()
+    { return this; }
+
 protected:
     virtual void accept0(NameVisitor *visitor);
 
@@ -211,6 +235,12 @@ public:
 
     virtual bool isEqualTo(const Name *other) const;
 
+    virtual const OperatorNameId *asOperatorNameId() const
+    { return this; }
+
+    virtual OperatorNameId *asOperatorNameId()
+    { return this; }
+
 protected:
     virtual void accept0(NameVisitor *visitor);
 
@@ -228,6 +258,12 @@ public:
 
     virtual bool isEqualTo(const Name *other) const;
 
+    virtual const ConversionNameId *asConversionNameId() const
+    { return this; }
+
+    virtual ConversionNameId *asConversionNameId()
+    { return this; }
+
 protected:
     virtual void accept0(NameVisitor *visitor);
 
diff --git a/src/shared/cplusplus/Symbol.cpp b/src/shared/cplusplus/Symbol.cpp
index cdcd389118859866f8bae91541dac2453af57bc1..8e9ba22bb78f5c034c054c69cb3eede9837e76f1 100644
--- a/src/shared/cplusplus/Symbol.cpp
+++ b/src/shared/cplusplus/Symbol.cpp
@@ -320,102 +320,36 @@ bool Symbol::isPrivate() const
 { return _visibility == Private; }
 
 bool Symbol::isScopedSymbol() const
-{ return dynamic_cast<const ScopedSymbol *>(this) != 0; }
+{ return asScopedSymbol() != 0; }
 
 bool Symbol::isEnum() const
-{ return dynamic_cast<const Enum *>(this) != 0; }
+{ return asEnum()  != 0; }
 
 bool Symbol::isFunction() const
-{ return dynamic_cast<const Function *>(this) != 0; }
+{ return asFunction() != 0; }
 
 bool Symbol::isNamespace() const
-{ return dynamic_cast<const Namespace *>(this) != 0; }
+{ return asNamespace() != 0; }
 
 bool Symbol::isClass() const
-{ return dynamic_cast<const Class *>(this) != 0; }
+{ return asClass() != 0; }
 
 bool Symbol::isBlock() const
-{ return dynamic_cast<const Block *>(this) != 0; }
+{ return asBlock() != 0; }
 
 bool Symbol::isUsingNamespaceDirective() const
-{ return dynamic_cast<const UsingNamespaceDirective *>(this) != 0; }
+{ return asUsingNamespaceDirective() != 0; }
 
 bool Symbol::isUsingDeclaration() const
-{ return dynamic_cast<const UsingDeclaration *>(this) != 0; }
+{ return asUsingDeclaration() != 0; }
 
 bool Symbol::isDeclaration() const
-{ return dynamic_cast<const Declaration *>(this) != 0; }
+{ return asDeclaration() != 0; }
 
 bool Symbol::isArgument() const
-{ return dynamic_cast<const Argument *>(this) != 0; }
+{ return asArgument() != 0; }
 
 bool Symbol::isBaseClass() const
-{ return dynamic_cast<const BaseClass *>(this) != 0; }
-
-const ScopedSymbol *Symbol::asScopedSymbol() const
-{ return dynamic_cast<const ScopedSymbol *>(this); }
-
-const Enum *Symbol::asEnum() const
-{ return dynamic_cast<const Enum *>(this); }
-
-const Function *Symbol::asFunction() const
-{ return dynamic_cast<const Function *>(this); }
-
-const Namespace *Symbol::asNamespace() const
-{ return dynamic_cast<const Namespace *>(this); }
-
-const Class *Symbol::asClass() const
-{ return dynamic_cast<const Class *>(this); }
-
-const Block *Symbol::asBlock() const
-{ return dynamic_cast<const Block *>(this); }
-
-const UsingNamespaceDirective *Symbol::asUsingNamespaceDirective() const
-{ return dynamic_cast<const UsingNamespaceDirective *>(this); }
-
-const UsingDeclaration *Symbol::asUsingDeclaration() const
-{ return dynamic_cast<const UsingDeclaration *>(this); }
-
-const Declaration *Symbol::asDeclaration() const
-{ return dynamic_cast<const Declaration *>(this); }
-
-const Argument *Symbol::asArgument() const
-{ return dynamic_cast<const Argument *>(this); }
-
-const BaseClass *Symbol::asBaseClass() const
-{ return dynamic_cast<const BaseClass *>(this); }
-
-ScopedSymbol *Symbol::asScopedSymbol()
-{ return dynamic_cast<ScopedSymbol *>(this); }
-
-Enum *Symbol::asEnum()
-{ return dynamic_cast<Enum *>(this); }
-
-Function *Symbol::asFunction()
-{ return dynamic_cast<Function *>(this); }
-
-Namespace *Symbol::asNamespace()
-{ return dynamic_cast<Namespace *>(this); }
-
-Class *Symbol::asClass()
-{ return dynamic_cast<Class *>(this); }
-
-Block *Symbol::asBlock()
-{ return dynamic_cast<Block *>(this); }
-
-UsingNamespaceDirective *Symbol::asUsingNamespaceDirective()
-{ return dynamic_cast<UsingNamespaceDirective *>(this); }
-
-UsingDeclaration *Symbol::asUsingDeclaration()
-{ return dynamic_cast<UsingDeclaration *>(this); }
-
-Declaration *Symbol::asDeclaration()
-{ return dynamic_cast<Declaration *>(this); }
-
-Argument *Symbol::asArgument()
-{ return dynamic_cast<Argument *>(this); }
-
-BaseClass *Symbol::asBaseClass()
-{ return dynamic_cast<BaseClass *>(this); }
+{ return asBaseClass() != 0; }
 
 CPLUSPLUS_END_NAMESPACE
diff --git a/src/shared/cplusplus/Symbol.h b/src/shared/cplusplus/Symbol.h
index e9d150e8d5e7be431771c0202458b698be771e38..2b9a428dce9bcad49254692afad2e7cb4cafb0cc 100644
--- a/src/shared/cplusplus/Symbol.h
+++ b/src/shared/cplusplus/Symbol.h
@@ -197,29 +197,29 @@ public:
     /// Returns true if this Symbol is a BaseClass.
     bool isBaseClass() const;
 
-    const ScopedSymbol *asScopedSymbol() const;
-    const Enum *asEnum() const;
-    const Function *asFunction() const;
-    const Namespace *asNamespace() const;
-    const Class *asClass() const;
-    const Block *asBlock() const;
-    const UsingNamespaceDirective *asUsingNamespaceDirective() const;
-    const UsingDeclaration *asUsingDeclaration() const;
-    const Declaration *asDeclaration() const;
-    const Argument *asArgument() const;
-    const BaseClass *asBaseClass() const;
-
-    ScopedSymbol *asScopedSymbol();
-    Enum *asEnum();
-    Function *asFunction();
-    Namespace *asNamespace();
-    Class *asClass();
-    Block *asBlock();
-    UsingNamespaceDirective *asUsingNamespaceDirective();
-    UsingDeclaration *asUsingDeclaration();
-    Declaration *asDeclaration();
-    Argument *asArgument();
-    BaseClass *asBaseClass();
+    virtual const ScopedSymbol *asScopedSymbol() const { return 0; }
+    virtual const Enum *asEnum() const { return 0; }
+    virtual const Function *asFunction() const { return 0; }
+    virtual const Namespace *asNamespace() const { return 0; }
+    virtual const Class *asClass() const { return 0; }
+    virtual const Block *asBlock() const { return 0; }
+    virtual const UsingNamespaceDirective *asUsingNamespaceDirective() const { return 0; }
+    virtual const UsingDeclaration *asUsingDeclaration() const { return 0; }
+    virtual const Declaration *asDeclaration() const { return 0; }
+    virtual const Argument *asArgument() const { return 0; }
+    virtual const BaseClass *asBaseClass() const { return 0; }
+
+    virtual ScopedSymbol *asScopedSymbol() { return 0; }
+    virtual Enum *asEnum() { return 0; }
+    virtual Function *asFunction() { return 0; }
+    virtual Namespace *asNamespace() { return 0; }
+    virtual Class *asClass() { return 0; }
+    virtual Block *asBlock() { return 0; }
+    virtual UsingNamespaceDirective *asUsingNamespaceDirective() { return 0; }
+    virtual UsingDeclaration *asUsingDeclaration() { return 0; }
+    virtual Declaration *asDeclaration() { return 0; }
+    virtual Argument *asArgument() { return 0; }
+    virtual BaseClass *asBaseClass() { return 0; }
 
     /// Returns this Symbol's type.
     virtual FullySpecifiedType type() const = 0;
diff --git a/src/shared/cplusplus/Symbols.h b/src/shared/cplusplus/Symbols.h
index c69483a2519f99cb3cb9fcd68ca26ea0acbba3ac..c7b3e924b4fe6b277b8fd98281bfc1c0091a2a9b 100644
--- a/src/shared/cplusplus/Symbols.h
+++ b/src/shared/cplusplus/Symbols.h
@@ -71,6 +71,12 @@ public:
     // Symbol's interface
     virtual FullySpecifiedType type() const;
 
+    virtual const UsingNamespaceDirective *asUsingNamespaceDirective() const
+    { return this; }
+
+    virtual UsingNamespaceDirective *asUsingNamespaceDirective()
+    { return this; }
+
 protected:
     virtual void visitSymbol0(SymbolVisitor *visitor);
 };
@@ -84,6 +90,12 @@ public:
     // Symbol's interface
     virtual FullySpecifiedType type() const;
 
+    virtual const UsingDeclaration *asUsingDeclaration() const
+    { return this; }
+
+    virtual UsingDeclaration *asUsingDeclaration()
+    { return this; }
+
 protected:
     virtual void visitSymbol0(SymbolVisitor *visitor);
 };
@@ -105,6 +117,12 @@ public:
     // Symbol's interface
     virtual FullySpecifiedType type() const;
 
+    virtual const Declaration *asDeclaration() const
+    { return this; }
+
+    virtual Declaration *asDeclaration()
+    { return this; }
+
 protected:
     virtual void visitSymbol0(SymbolVisitor *visitor);
 
@@ -127,6 +145,12 @@ public:
     // Symbol's interface
     virtual FullySpecifiedType type() const;
 
+    virtual const Argument *asArgument() const
+    { return this; }
+
+    virtual Argument *asArgument()
+    { return this; }
+
 protected:
     virtual void visitSymbol0(SymbolVisitor *visitor);
 
@@ -146,6 +170,12 @@ public:
     Scope *members() const;
     void addMember(Symbol *member);
 
+    virtual const ScopedSymbol *asScopedSymbol() const
+    { return this; }
+
+    virtual ScopedSymbol *asScopedSymbol()
+    { return this; }
+
 private:
     Scope *_members;
 };
@@ -159,6 +189,12 @@ public:
     // Symbol's interface
     virtual FullySpecifiedType type() const;
 
+    virtual const Block *asBlock() const
+    { return this; }
+
+    virtual Block *asBlock()
+    { return this; }
+
 protected:
     virtual void visitSymbol0(SymbolVisitor *visitor);
 };
@@ -175,6 +211,12 @@ public:
     // Type's interface
     virtual bool isEqualTo(const Type *other) const;
 
+    virtual const Enum *asEnum() const
+    { return this; }
+
+    virtual Enum *asEnum()
+    { return this; }
+
 protected:
     virtual void visitSymbol0(SymbolVisitor *visitor);
     virtual void accept0(TypeVisitor *visitor);
@@ -230,6 +272,12 @@ public:
     // Type's interface
     virtual bool isEqualTo(const Type *other) const;
 
+    virtual const Function *asFunction() const
+    { return this; }
+
+    virtual Function *asFunction()
+    { return this; }
+
 protected:
     virtual void visitSymbol0(SymbolVisitor *visitor);
     virtual void accept0(TypeVisitor *visitor);
@@ -264,6 +312,12 @@ public:
     // Type's interface
     virtual bool isEqualTo(const Type *other) const;
 
+    virtual const Namespace *asNamespace() const
+    { return this; }
+
+    virtual Namespace *asNamespace()
+    { return this; }
+
 protected:
     virtual void visitSymbol0(SymbolVisitor *visitor);
     virtual void accept0(TypeVisitor *visitor);
@@ -281,6 +335,12 @@ public:
     // Symbol's interface
     virtual FullySpecifiedType type() const;
 
+    virtual const BaseClass *asBaseClass() const
+    { return this; }
+
+    virtual BaseClass *asBaseClass()
+    { return this; }
+
 protected:
     virtual void visitSymbol0(SymbolVisitor *visitor);
 
@@ -322,6 +382,12 @@ public:
     // Type's interface
     virtual bool isEqualTo(const Type *other) const;
 
+    virtual const Class *asClass() const
+    { return this; }
+
+    virtual Class *asClass()
+    { return this; }
+
 protected:
     virtual void visitSymbol0(SymbolVisitor *visitor);
     virtual void accept0(TypeVisitor *visitor);