summaryrefslogtreecommitdiff
path: root/shared
diff options
context:
space:
mode:
authorRoberto Raggi <qtc-committer@nokia.com>2009-01-03 13:02:37 +0100
committerRoberto Raggi <qtc-committer@nokia.com>2009-01-03 13:02:37 +0100
commit722ccd9e0d39013754e383ff4b33943b9961f580 (patch)
treeaeb88379c68b2d4052948646670b214359410c23 /shared
parent8d91577df9b9128854ae1090802a3336c6c0668a (diff)
downloadqt-creator-722ccd9e0d39013754e383ff4b33943b9961f580.tar.gz
Initial implementation of the pretty printer.
Diffstat (limited to 'shared')
-rw-r--r--shared/cplusplus/PrettyPrinter.cpp1223
-rw-r--r--shared/cplusplus/PrettyPrinter.h162
-rw-r--r--shared/cplusplus/cplusplus.pri7
3 files changed, 1390 insertions, 2 deletions
diff --git a/shared/cplusplus/PrettyPrinter.cpp b/shared/cplusplus/PrettyPrinter.cpp
new file mode 100644
index 0000000000..1cf8aad143
--- /dev/null
+++ b/shared/cplusplus/PrettyPrinter.cpp
@@ -0,0 +1,1223 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+**
+** Non-Open Source Usage
+**
+** Licensees may use this file in accordance with the Qt Beta Version
+** License Agreement, Agreement version 2.2 provided with the Software or,
+** alternatively, in accordance with the terms contained in a written
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the packaging
+** of this file. Please review the following information to ensure GNU
+** General Public Licensing requirements will be met:
+**
+** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt GPL Exception
+** version 1.3, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+
+#include "PrettyPrinter.h"
+#include "AST.h"
+#include <iostream>
+#include <string>
+
+CPLUSPLUS_USE_NAMESPACE
+
+PrettyPrinter::PrettyPrinter(Control *control, std::ostream &out)
+ : ASTVisitor(control),
+ out(out),
+ depth(0)
+{ }
+
+void PrettyPrinter::operator()(AST *ast)
+{ accept(ast); }
+
+void PrettyPrinter::indent()
+{ ++depth; }
+
+void PrettyPrinter::deindent()
+{ --depth; }
+
+void PrettyPrinter::newline()
+{ out << '\n' << std::string(depth * 4, ' '); }
+
+bool PrettyPrinter::visit(AccessDeclarationAST *ast)
+{
+ deindent();
+ newline();
+ out << spell(ast->access_specifier_token);
+ if (ast->slots_token)
+ out << ' ' << spell(ast->slots_token);
+ out << ':' << std::endl;
+ indent();
+ return false;
+}
+
+bool PrettyPrinter::visit(ArrayAccessAST *ast)
+{
+ out << '[';
+ accept(ast->expression);
+ out << ']';
+ return false;
+}
+
+bool PrettyPrinter::visit(ArrayDeclaratorAST *ast)
+{
+ out << '[';
+ accept(ast->expression);
+ out << ']';
+ return false;
+}
+
+bool PrettyPrinter::visit(ArrayInitializerAST *ast)
+{
+ out << '{';
+ for (ExpressionListAST *it = ast->expression_list; it; it = it->next) {
+ accept(it->expression);
+ if (it->next)
+ out << ", ";
+ }
+ out << '}';
+ return false;
+}
+
+bool PrettyPrinter::visit(AsmDefinitionAST *ast)
+{
+ out << spell(ast->asm_token);
+ for (SpecifierAST *it = ast->cv_qualifier_seq; it; it = it->next) {
+ out << ' ';
+ accept(it);
+ }
+ out << '(';
+ out << "/* ### implement me */";
+ out << ");";
+ return false;
+}
+
+bool PrettyPrinter::visit(AttributeSpecifierAST *ast)
+{
+ out << "attribute((";
+ for (AttributeAST *it = ast->attributes; it; it = it->next) {
+ accept(it);
+ if (it->next)
+ out << ", ";
+ }
+ out << "))";
+ return false;
+}
+
+bool PrettyPrinter::visit(AttributeAST *ast)
+{
+ out << spell(ast->identifier_token);
+ if (ast->lparen_token) {
+ out << '(';
+ out << spell(ast->tag_token);
+ if (ast->expression_list) {
+ out << '(';
+ for (ExpressionListAST *it = ast->expression_list; it; it = it->next) {
+ accept(it->expression);
+ if (it->next)
+ out << ", ";
+ }
+ out << ')';
+ }
+ out << ')';
+ }
+ return false;
+}
+
+bool PrettyPrinter::visit(BaseSpecifierAST *ast)
+{
+ if (ast->token_virtual && ast->token_access_specifier) {
+ out << "virtual ";
+ out << spell(ast->token_access_specifier);
+ } else if (ast->token_virtual) {
+ out << "virtual";
+ } else if (ast->token_access_specifier) {
+ out << spell(ast->token_access_specifier);
+ }
+ accept(ast->name);
+ return false;
+}
+
+bool PrettyPrinter::visit(BinaryExpressionAST *ast)
+{
+ accept(ast->left_expression);
+ out << ' ' << spell(ast->binary_op_token) << ' ';
+ accept(ast->right_expression);
+ return false;
+}
+
+bool PrettyPrinter::visit(BoolLiteralAST *ast)
+{
+ out << spell(ast->token);
+ return false;
+}
+
+bool PrettyPrinter::visit(BreakStatementAST *)
+{
+ out << "break;";
+ return false;
+}
+
+bool PrettyPrinter::visit(CallAST *ast)
+{
+ out << '(';
+ for (ExpressionListAST *it = ast->expression_list; it; it = it->next) {
+ accept(it->expression);
+ if (it->next)
+ out << ", ";
+ }
+ out << ')';
+ return false;
+}
+
+bool PrettyPrinter::visit(CaseStatementAST *ast)
+{
+ out << "case ";
+ accept(ast->expression);
+ out << ':';
+ accept(ast->statement);
+ return false;
+}
+
+bool PrettyPrinter::visit(CastExpressionAST *ast)
+{
+ out << '(';
+ accept(ast->type_id);
+ out << ')';
+ accept(ast->expression);
+ return false;
+}
+
+bool PrettyPrinter::visit(CatchClauseAST *ast)
+{
+ out << "catch";
+ out << '(';
+ accept(ast->exception_declaration);
+ out << ')';
+ accept(ast->statement);
+ return false;
+}
+
+bool PrettyPrinter::visit(ClassSpecifierAST *ast)
+{
+ out << spell(ast->classkey_token);
+ out << ' ';
+ if (ast->attributes) {
+ accept(ast->attributes);
+ out << ' ';
+ }
+ accept(ast->name);
+ if (ast->colon_token) {
+ out << ':';
+ out << ' ';
+ for (BaseSpecifierAST *it = ast->base_clause; it; it = it->next) {
+ accept(it);
+ if (it->next)
+ out << ", ";
+ }
+ }
+ out << '{';
+ if (ast->member_specifiers) {
+ indent();
+ newline();
+ if (ast->member_specifiers) {
+ for (DeclarationAST *it = ast->member_specifiers; it; it = it->next) {
+ accept(it);
+ if (it->next)
+ newline();
+ }
+ }
+ deindent();
+ newline();
+ }
+ out << '}';
+ return false;
+}
+
+bool PrettyPrinter::visit(CompoundStatementAST *ast)
+{
+ out << '{';
+ if (ast->statements) {
+ indent();
+ newline();
+ for (StatementAST *it = ast->statements; it; it = it->next) {
+ accept(it);
+ if (it->next)
+ newline();
+ }
+ deindent();
+ newline();
+ }
+ out << '}';
+ return false;
+}
+
+bool PrettyPrinter::visit(ConditionAST *ast)
+{
+ for (SpecifierAST *it = ast->type_specifier; it; it = it->next) {
+ accept(it);
+ if (it->next)
+ out << ' ';
+ }
+ if (ast->declarator) {
+ if (ast->type_specifier)
+ out << ' ';
+
+ accept(ast->declarator);
+ }
+ return false;
+}
+
+bool PrettyPrinter::visit(ConditionalExpressionAST *ast)
+{
+ accept(ast->condition);
+ out << '?';
+ accept(ast->left_expression);
+ out << ':';
+ accept(ast->right_expression);
+ return false;
+}
+
+bool PrettyPrinter::visit(ContinueStatementAST *)
+{
+ out << "continue";
+ out << ';';
+ return false;
+}
+
+bool PrettyPrinter::visit(ConversionFunctionIdAST *ast)
+{
+ out << "operator";
+ out << ' ';
+ for (SpecifierAST *it = ast->type_specifier; it; it = it->next) {
+ accept(it);
+ if (it->next)
+ out << ' ';
+ }
+ for (PtrOperatorAST *it = ast->ptr_operators; it; it = it->next) {
+ accept(it);
+ }
+ return false;
+}
+
+bool PrettyPrinter::visit(CppCastExpressionAST *ast)
+{
+ out << spell(ast->cast_token);
+ out << '<';
+ out << ' ';
+ accept(ast->type_id);
+ out << ' ';
+ out << '>';
+ out << '(';
+ accept(ast->expression);
+ out << ')';
+ return false;
+}
+
+bool PrettyPrinter::visit(CtorInitializerAST *ast)
+{
+ out << ':';
+ out << ' ';
+ for (MemInitializerAST *it = ast->member_initializers; it; it = it->next) {
+ accept(it->name);
+ out << '(';
+ accept(it->expression);
+ out << ')';
+ if (it->next)
+ out << ", ";
+ }
+ return false;
+}
+
+bool PrettyPrinter::visit(DeclaratorAST *ast)
+{
+ for (PtrOperatorAST *it = ast->ptr_operators; it; it = it->next) {
+ accept(it);
+ }
+ if (ast->core_declarator) {
+ if (ast->ptr_operators)
+ out << ' ';
+ accept(ast->core_declarator);
+ }
+ for (PostfixDeclaratorAST *it = ast->postfix_declarators; it; it = it->next) {
+ accept(it);
+ }
+ for (SpecifierAST *it = ast->attributes; it; it = it->next) {
+ accept(it);
+ if (it->next)
+ out << ' ';
+ }
+ if (ast->initializer) {
+ out << '=';
+ out << ' ';
+ accept(ast->initializer);
+ }
+ return false;
+}
+
+bool PrettyPrinter::visit(DeclarationStatementAST *ast)
+{
+ accept(ast->declaration);
+ return false;
+}
+
+bool PrettyPrinter::visit(DeclaratorIdAST *ast)
+{
+ accept(ast->name);
+ return false;
+}
+
+bool PrettyPrinter::visit(DeclaratorListAST *)
+{
+ assert(0);
+ return false;
+}
+
+bool PrettyPrinter::visit(DeleteExpressionAST *ast)
+{
+ if (ast->scope_token)
+ out << "::";
+ out << "delete";
+ if (ast->expression) {
+ out << ' ';
+ accept(ast->expression);
+ }
+ return false;
+}
+
+bool PrettyPrinter::visit(DestructorNameAST *ast)
+{
+ out << '~';
+ out << spell(ast->identifier_token);
+ return false;
+}
+
+bool PrettyPrinter::visit(DoStatementAST *ast)
+{
+ out << "do";
+ if (ast->statement) {
+ out << ' ';
+ accept(ast->statement);
+ }
+ out << "while";
+ out << '(';
+ accept(ast->expression);
+ out << ')';
+ out << ';';
+ return false;
+}
+
+bool PrettyPrinter::visit(ElaboratedTypeSpecifierAST *ast)
+{
+ out << spell(ast->classkey_token);
+ if (ast->name) {
+ out << ' ';
+ accept(ast->name);
+ }
+ return false;
+}
+
+bool PrettyPrinter::visit(EmptyDeclarationAST *)
+{
+ out << ';';
+ return false;
+}
+
+bool PrettyPrinter::visit(EnumSpecifierAST *ast)
+{
+ out << "enum";
+ if (ast->name) {
+ out << ' ';
+ accept(ast->name);
+ }
+ out << '{';
+ for (EnumeratorAST *it = ast->enumerators; it; it = it->next) {
+ accept(it);
+ if (it->next)
+ out << ", ";
+ }
+ out << '}';
+ return false;
+}
+
+bool PrettyPrinter::visit(EnumeratorAST *ast)
+{
+ out << spell(ast->identifier_token);
+ if (ast->equal_token) {
+ out << ' ';
+ out << '=';
+ out << ' ';
+ accept(ast->expression);
+ }
+ return false;
+}
+
+bool PrettyPrinter::visit(ExceptionDeclarationAST *ast)
+{
+ for (SpecifierAST *it = ast->type_specifier; it; it = it->next) {
+ accept(it);
+ if (it->next)
+ out << ' ';
+ }
+ if (ast->declarator) {
+ if (ast->type_specifier)
+ out << ' ';
+ accept(ast->declarator);
+ }
+ if (ast->dot_dot_dot_token)
+ out << "...";
+ return false;
+}
+
+bool PrettyPrinter::visit(ExceptionSpecificationAST *ast)
+{
+ out << "throw";
+ out << '(';
+ if (ast->dot_dot_dot_token)
+ out << "...";
+ else {
+ for (ExpressionListAST *it = ast->type_ids; it; it = it->next) {
+ accept(it->expression);
+ if (it->next)
+ out << ", ";
+ }
+ }
+ out << ')';
+ return false;
+}
+
+bool PrettyPrinter::visit(ExpressionListAST *ast)
+{
+ for (ExpressionListAST *it = ast; it; it = it->next) {
+ accept(it->expression);
+ if (it->next)
+ out << ", ";
+ }
+ return false;
+}
+
+bool PrettyPrinter::visit(ExpressionOrDeclarationStatementAST *ast)
+{
+ accept(ast->declaration);
+ return false;
+}
+
+bool PrettyPrinter::visit(ExpressionStatementAST *ast)
+{
+ accept(ast->expression);
+ out << ';';
+ return false;
+}
+
+bool PrettyPrinter::visit(ForStatementAST *ast)
+{
+ out << "for";
+ out << ' ';
+ out << '(';
+ accept(ast->initializer);
+ accept(ast->condition);
+ out << ';';
+ accept(ast->expression);
+ out << ')';
+ accept(ast->statement);
+ return false;
+}
+
+bool PrettyPrinter::visit(FunctionDeclaratorAST *ast)
+{
+ out << '(';
+ accept(ast->parameters);
+ out << ')';
+ for (SpecifierAST *it = ast->cv_qualifier_seq; it; it = it->next) {
+ accept(it);
+ if (it->next)
+ out << ' ';
+ }
+ if (ast->exception_specification) {
+ out << ' ';
+ accept(ast->exception_specification);
+ }
+ return false;
+}
+
+bool PrettyPrinter::visit(FunctionDefinitionAST *ast)
+{
+ for (SpecifierAST *it = ast->decl_specifier_seq; it; it = it->next) {
+ accept(it);
+ if (it->next)
+ out << ' ';
+ }
+ if (ast->declarator) {
+ if (ast->decl_specifier_seq)
+ out << ' ';
+ accept(ast->declarator);
+ }
+ accept(ast->ctor_initializer);
+ newline();
+ accept(ast->function_body);
+ if (ast->next)
+ newline(); // one extra line after the function definiton.
+ return false;
+}
+
+bool PrettyPrinter::visit(GotoStatementAST *ast)
+{
+ out << "goto";
+ out << ' ';
+ out << spell(ast->identifier_token);
+ out << ';';
+ return false;
+}
+
+bool PrettyPrinter::visit(IfStatementAST *ast)
+{
+ out << "if";
+ out << ' ';
+ out << '(';
+ accept(ast->condition);
+ out << ')';
+ if (ast->statement->asCompoundStatement())
+ accept(ast->statement);
+ else {
+ indent();
+ newline();
+ accept(ast->statement);
+ deindent();
+ newline();
+ }
+ if (ast->else_token) {
+ out << "else";
+ out << ' ';
+ accept(ast->else_statement);
+ }
+ return false;
+}
+
+bool PrettyPrinter::visit(LabeledStatementAST *ast)
+{
+ out << spell(ast->label_token);
+ out << ':';
+ accept(ast->statement);
+ return false;
+}
+
+bool PrettyPrinter::visit(LinkageBodyAST *ast)
+{
+ out << '{';
+ if (ast->declarations) {
+ indent();
+ newline();
+ for (DeclarationAST *it = ast->declarations; it; it = it->next) {
+ accept(it);
+ if (it->next)
+ newline();
+ }
+ deindent();
+ newline();
+ }
+ out << '}';
+ return false;
+}
+
+bool PrettyPrinter::visit(LinkageSpecificationAST *ast)
+{
+ out << "extern";
+ out << ' ';
+ if (ast->extern_type) {
+ out << '"' << spell(ast->extern_type) << '"';
+ out << ' ';
+ }
+
+ accept(ast->declaration);
+ return false;
+}
+
+bool PrettyPrinter::visit(MemInitializerAST *ast)
+{
+ accept(ast->name);
+ out << '(';
+ accept(ast->expression);
+ out << ')';
+ return false;
+}
+
+bool PrettyPrinter::visit(MemberAccessAST *ast)
+{
+ out << spell(ast->access_token);
+ if (ast->template_token) {
+ out << "template";
+ out << ' ';
+ }
+ accept(ast->member_name);
+ return false;
+}
+
+bool PrettyPrinter::visit(NamedTypeSpecifierAST *ast)
+{
+ accept(ast->name);
+ return false;
+}
+
+bool PrettyPrinter::visit(NamespaceAST *ast)
+{
+ out << "namespace";
+ if (ast->identifier_token) {
+ out << ' ';
+ out << spell(ast->identifier_token);
+ }
+ for (SpecifierAST *it = ast->attributes; it; it = it->next) {
+ out << ' ';
+ accept(it);
+ }
+ out << ' ';
+ accept(ast->linkage_body);
+ return false;
+}
+
+bool PrettyPrinter::visit(NamespaceAliasDefinitionAST *ast)
+{
+ out << "namespace";
+ out << ' ';
+ out << spell(ast->namespace_name);
+ out << ' ';
+ out << '=';
+ out << ' ';
+ accept(ast->name);
+ out << ';';
+ return false;
+}
+
+bool PrettyPrinter::visit(NestedDeclaratorAST *ast)
+{
+ out << '(';
+ accept(ast->declarator);
+ out << ')';
+ return false;
+}
+
+bool PrettyPrinter::visit(NestedExpressionAST *ast)
+{
+ out << '(';
+ accept(ast->expression);
+ out << ')';
+ return false;
+}
+
+bool PrettyPrinter::visit(NestedNameSpecifierAST *ast)
+{
+ accept(ast->class_or_namespace_name);
+ if (ast->scope_token)
+ out << "::";
+ return false;
+}
+
+bool PrettyPrinter::visit(NewDeclaratorAST *ast)
+{
+ for (PtrOperatorAST *it = ast->ptr_operators; it; it = it->next) {
+ accept(it);
+ if (it->next)
+ out << ' ';
+ }
+ if (ast->declarator)
+ accept(ast->declarator);
+ return false;
+}
+
+bool PrettyPrinter::visit(NewExpressionAST *ast)
+{
+ if (ast->scope_token)
+ out << "::";
+ out << "new";
+ out << ' ';
+ if (ast->expression) {
+ accept(ast->expression);
+ if (ast->type_id)
+ out << ' ';
+ }
+ if (ast->type_id) {
+ accept(ast->type_id);
+ if (ast->new_type_id)
+ out << ' ';
+ }
+ if (ast->new_type_id) {
+ accept(ast->new_type_id);
+ if (ast->new_initializer)
+ out << ' ';
+ }
+ accept(ast->new_initializer);
+ return false;
+}
+
+bool PrettyPrinter::visit(NewInitializerAST *ast)
+{
+ out << '(';
+ accept(ast->expression);
+ out << ')';
+ return false;
+}
+
+bool PrettyPrinter::visit(NewTypeIdAST *ast)
+{
+ for (SpecifierAST *it = ast->type_specifier; it; it = it->next) {
+ accept(it);
+ if (it->next)
+ out << ' ';
+ }
+ if (ast->type_specifier)
+ out << ' ';
+ if (ast->new_initializer) {
+ accept(ast->new_initializer);
+ if (ast->new_declarator)
+ out << ' ';
+ }
+ accept(ast->new_declarator);
+ return false;
+}
+
+bool PrettyPrinter::visit(NumericLiteralAST *ast)
+{
+ out << spell(ast->token);
+ return false;
+}
+
+bool PrettyPrinter::visit(OperatorAST *ast)
+{
+ out << spell(ast->op_token);
+ if (ast->open_token) {
+ out << spell(ast->open_token);
+ out << spell(ast->close_token);
+ }
+ return false;
+}
+
+bool PrettyPrinter::visit(OperatorFunctionIdAST *ast)
+{
+ out << "operator";
+ out << ' ';
+ accept(ast->op);
+ return false;
+}
+
+bool PrettyPrinter::visit(ParameterDeclarationAST *ast)
+{
+ for (SpecifierAST *it = ast->type_specifier; it; it = it->next) {
+ accept(it);
+ if (it->next)
+ out << ' ';
+ }
+ if (ast->declarator) {
+ out << ' ';
+ accept(ast->declarator);
+ }
+ if (ast->equal_token) {
+ out << ' ';
+ out << '=';
+ out << ' ';
+ }
+ accept(ast->expression);
+ return false;
+}
+
+bool PrettyPrinter::visit(ParameterDeclarationClauseAST *ast)
+{
+ for (DeclarationAST *it = ast->parameter_declarations; it; it = it->next) {
+ accept(it);
+ if (it->next)
+ out << ", ";
+ }
+ return false;
+}
+
+bool PrettyPrinter::visit(PointerAST *ast)
+{
+ out << '*';
+ for (SpecifierAST *it = ast->cv_qualifier_seq; it; it = it->next) {
+ accept(it);
+ if (it->next)
+ out << ' ';
+ }
+ return false;
+}
+
+bool PrettyPrinter::visit(PointerToMemberAST *ast)
+{
+ if (ast->global_scope_token)
+ out << "::";
+ for (NestedNameSpecifierAST *it = ast->nested_name_specifier; it; it = it->next) {
+ accept(it);
+ }
+ out << '*';
+ for (SpecifierAST *it = ast->cv_qualifier_seq; it; it = it->next) {
+ accept(it);
+ if (it->next)
+ out << ' ';
+ }
+ return false;
+}
+
+bool PrettyPrinter::visit(PostIncrDecrAST *ast)
+{
+ out << spell(ast->incr_decr_token);
+ return false;
+}
+
+bool PrettyPrinter::visit(PostfixExpressionAST *ast)
+{
+ accept(ast->base_expression);
+ for (PostfixAST *it = ast->postfix_expressions; it; it = it->next) {
+ accept(it);
+ }
+ return false;
+}
+
+bool PrettyPrinter::visit(QualifiedNameAST *ast)
+{
+ if (ast->global_scope_token)
+ out << "::";
+ for (NestedNameSpecifierAST *it = ast->nested_name_specifier; it; it = it->next) {
+ accept(it);
+ }
+ accept(ast->unqualified_name);
+ return false;
+}
+
+bool PrettyPrinter::visit(ReferenceAST *)
+{
+ out << '&';
+ return false;
+}
+
+bool PrettyPrinter::visit(ReturnStatementAST *ast)
+{
+ out << "return";
+ if (ast->expression) {
+ out << ' ';
+ accept(ast->expression);
+ }
+ out << ';';
+ return false;
+}
+
+bool PrettyPrinter::visit(SimpleDeclarationAST *ast)
+{
+ for (SpecifierAST *it = ast->decl_specifier_seq; it; it = it->next) {
+ accept(it);
+ if (it->next)
+ out << ' ';
+ }
+ if (ast->declarators) {
+ if (ast->decl_specifier_seq)
+ out << ' ';
+
+ for (DeclaratorListAST *it = ast->declarators; it; it = it->next) {
+ accept(it->declarator);
+ if (it->next)
+ out << ", ";
+ }
+ }
+ out << ';';
+ return false;
+}
+
+bool PrettyPrinter::visit(SimpleNameAST *ast)
+{
+ out << spell(ast->identifier_token);
+ return false;
+}
+
+bool PrettyPrinter::visit(SimpleSpecifierAST *ast)
+{
+ out << spell(ast->specifier_token);
+ return false;
+}
+
+bool PrettyPrinter::visit(SizeofExpressionAST *ast)
+{
+ out << "sizeof";
+ out << ' ';
+ accept(ast->expression);
+ return false;
+}
+
+bool PrettyPrinter::visit(StringLiteralAST *ast)
+{
+ out << '"' << spell(ast->token) << '"';
+ if (ast->next) {
+ out << ' ';
+ accept(ast->next);
+ }
+ return false;
+}
+
+bool PrettyPrinter::visit(SwitchStatementAST *ast)
+{
+ out << "switch";
+ out << ' ';
+ out << '(';
+ accept(ast->condition);
+ out << ')';
+ accept(ast->statement);
+ return false;
+}
+
+bool PrettyPrinter::visit(TemplateArgumentListAST *ast)
+{
+ for (TemplateArgumentListAST *it = ast; it; it = it->next) {
+ accept(it->template_argument);
+ if (it->next)
+ out << ", ";
+ }
+ return false;
+}
+
+bool PrettyPrinter::visit(TemplateDeclarationAST *ast)
+{
+ if (ast->export_token) {
+ out << "export";
+ out << ' ';
+ }
+ out << "template";
+ out << ' ';
+ out << '<';
+ if (ast->template_parameters) {
+ out << ' ';
+ for (DeclarationAST *it = ast->template_parameters; it; it = it->next) {
+ accept(it);
+ if (it->next)
+ out << ", ";
+ }
+ out << ' ';
+ }
+ out << '>';
+ newline();
+ accept(ast->declaration);
+ return false;
+}
+
+bool PrettyPrinter::visit(TemplateIdAST *ast)
+{
+ out << spell(ast->identifier_token);
+ out << '<';
+ if (ast->template_arguments) {
+ out << ' ';
+ for (TemplateArgumentListAST *it = ast->template_arguments; it; it = it->next) {
+ accept(it->template_argument);
+ if (it->next)
+ out << ", ";
+ }
+ out << ' ';
+ }
+ out << '>';
+ return false;
+}
+
+bool PrettyPrinter::visit(TemplateTypeParameterAST *ast)
+{
+ out << "template";
+ out << ' ';
+ out << '<';
+ if (ast->template_parameters) {
+ out << ' ';
+ for (DeclarationAST *it = ast->template_parameters; it; it = it->next) {
+ accept(it);
+ if (it->next)
+ out << ",. ";
+ }
+ out << ' ';
+ }
+ out << '>';
+ out << ' ';
+ out << "class";
+ out << ' ';
+ accept(ast->name);
+ if (ast->equal_token) {
+ out << ' ';
+ out << '=';
+ out << ' ';
+ accept(ast->type_id);
+ }
+ return false;
+}
+
+bool PrettyPrinter::visit(ThisExpressionAST *)
+{
+ out << "this";
+ return false;
+}
+
+bool PrettyPrinter::visit(ThrowExpressionAST *ast)
+{
+ out << "throw";
+ out << ' ';
+ accept(ast->expression);
+ return false;
+}
+
+bool PrettyPrinter::visit(TranslationUnitAST *ast)
+{
+ for (DeclarationAST *it = ast->declarations; it; it = it->next) {
+ accept(it);
+ if (it->next)
+ newline();
+ }
+ return false;
+}
+
+bool PrettyPrinter::visit(TryBlockStatementAST *ast)
+{
+ out << "try";
+ out << ' ';
+ accept(ast->statement);
+ for (CatchClauseAST *it = ast->catch_clause_seq; it; it = it->next) {
+ accept(it);
+ }
+ return false;
+}
+
+bool PrettyPrinter::visit(TypeConstructorCallAST *ast)
+{
+ for (SpecifierAST *it = ast->type_specifier; it; it = it->next) {
+ accept(it);
+ if (it->next)
+ out << ' ';
+ }
+ out << '(';
+ for (ExpressionListAST *it = ast->expression_list; it; it = it->next) {
+ accept(it->expression);
+ if (it->next)
+ out << ", ";
+ }
+ out << ')';
+ return false;
+}
+
+bool PrettyPrinter::visit(TypeIdAST *ast)
+{
+ for (SpecifierAST *it = ast->type_specifier; it; it = it->next) {
+ accept(it);
+ if (it->next)
+ out << ' ';
+ }
+ if (ast->type_specifier && ast->declarator) {
+ out << ' ';
+ accept(ast->declarator);
+ }
+ return false;
+}
+
+bool PrettyPrinter::visit(TypeidExpressionAST *ast)
+{
+ out << "typeid";
+ out << '(';
+ accept(ast->expression);
+ out << ')';
+ return false;
+}
+
+bool PrettyPrinter::visit(TypeofSpecifierAST *ast)
+{
+ out << "typeof";
+ out << '(';
+ accept(ast->expression);
+ out << ')';
+ return false;
+}
+
+bool PrettyPrinter::visit(TypenameCallExpressionAST *ast)
+{
+ out << "typename";
+ out << ' ';
+ accept(ast->name);
+ out << '(';
+ for (ExpressionListAST *it = ast->expression_list; it; it = it->next) {
+ accept(it->expression);
+ if (it->next)
+ out << ", ";
+ }
+ out << ')';
+ return false;
+}
+
+bool PrettyPrinter::visit(TypenameTypeParameterAST *ast)
+{
+ out << spell(ast->classkey_token);
+ if (ast->name) {
+ out << ' ';
+ accept(ast->name);
+ }
+ if (ast->equal_token) {
+ out << ' ';
+ out << '=';
+ out << ' ';
+ accept(ast->type_id);
+ }
+ return false;
+}
+
+bool PrettyPrinter::visit(UnaryExpressionAST *ast)
+{
+ out << spell(ast->unary_op_token);
+ accept(ast->expression);
+ return false;
+}
+
+bool PrettyPrinter::visit(UsingAST *ast)
+{
+ out << "using";
+ out << ' ';
+ if (ast->typename_token) {
+ out << "typename";
+ out << ' ';
+ }
+ accept(ast->name);
+ out << ';';
+ return false;
+}
+
+bool PrettyPrinter::visit(UsingDirectiveAST *ast)
+{
+ out << "using";
+ out << ' ';
+ out << "namespace";
+ out << ' ';
+ accept(ast->name);
+ out << ';';
+ return false;
+}
+
+bool PrettyPrinter::visit(WhileStatementAST *ast)
+{
+ out << "while";
+ out << ' ';
+ out << '(';
+ accept(ast->condition);
+ out << ')';
+ accept(ast->statement);
+ return false;
+}
+
+bool PrettyPrinter::visit(QtMethodAST *ast)
+{
+ out << ast->method_token;
+ out << '(';
+ accept(ast->declarator);
+ out << ')';
+ return false;
+}
diff --git a/shared/cplusplus/PrettyPrinter.h b/shared/cplusplus/PrettyPrinter.h
new file mode 100644
index 0000000000..966ebacd0e
--- /dev/null
+++ b/shared/cplusplus/PrettyPrinter.h
@@ -0,0 +1,162 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+**
+** Non-Open Source Usage
+**
+** Licensees may use this file in accordance with the Qt Beta Version
+** License Agreement, Agreement version 2.2 provided with the Software or,
+** alternatively, in accordance with the terms contained in a written
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the packaging
+** of this file. Please review the following information to ensure GNU
+** General Public Licensing requirements will be met:
+**
+** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt GPL Exception
+** version 1.3, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+
+#ifndef CPLUSPLUS_PRETTYPRINTER_H
+#define CPLUSPLUS_PRETTYPRINTER_H
+
+#include "CPlusPlusForwardDeclarations.h"
+#include "ASTVisitor.h"
+
+#include <iosfwd>
+
+CPLUSPLUS_BEGIN_HEADER
+CPLUSPLUS_BEGIN_NAMESPACE
+
+class PrettyPrinter: protected ASTVisitor
+{
+public:
+ PrettyPrinter(Control *control, std::ostream &out);
+
+ void operator()(AST *ast);
+
+protected:
+ virtual bool visit(AccessDeclarationAST *ast);
+ virtual bool visit(ArrayAccessAST *ast);
+ virtual bool visit(ArrayDeclaratorAST *ast);
+ virtual bool visit(ArrayInitializerAST *ast);
+ virtual bool visit(AsmDefinitionAST *ast);
+ virtual bool visit(AttributeSpecifierAST *ast);
+ virtual bool visit(AttributeAST *ast);
+ virtual bool visit(BaseSpecifierAST *ast);
+ virtual bool visit(BinaryExpressionAST *ast);
+ virtual bool visit(BoolLiteralAST *ast);
+ virtual bool visit(BreakStatementAST *ast);
+ virtual bool visit(CallAST *ast);
+ virtual bool visit(CaseStatementAST *ast);
+ virtual bool visit(CastExpressionAST *ast);
+ virtual bool visit(CatchClauseAST *ast);
+ virtual bool visit(ClassSpecifierAST *ast);
+ virtual bool visit(CompoundStatementAST *ast);
+ virtual bool visit(ConditionAST *ast);
+ virtual bool visit(ConditionalExpressionAST *ast);
+ virtual bool visit(ContinueStatementAST *ast);
+ virtual bool visit(ConversionFunctionIdAST *ast);
+ virtual bool visit(CppCastExpressionAST *ast);
+ virtual bool visit(CtorInitializerAST *ast);
+ virtual bool visit(DeclaratorAST *ast);
+ virtual bool visit(DeclarationStatementAST *ast);
+ virtual bool visit(DeclaratorIdAST *ast);
+ virtual bool visit(DeclaratorListAST *ast);
+ virtual bool visit(DeleteExpressionAST *ast);
+ virtual bool visit(DestructorNameAST *ast);
+ virtual bool visit(DoStatementAST *ast);
+ virtual bool visit(ElaboratedTypeSpecifierAST *ast);
+ virtual bool visit(EmptyDeclarationAST *ast);
+ virtual bool visit(EnumSpecifierAST *ast);
+ virtual bool visit(EnumeratorAST *ast);
+ virtual bool visit(ExceptionDeclarationAST *ast);
+ virtual bool visit(ExceptionSpecificationAST *ast);
+ virtual bool visit(ExpressionListAST *ast);
+ virtual bool visit(ExpressionOrDeclarationStatementAST *ast);
+ virtual bool visit(ExpressionStatementAST *ast);
+ virtual bool visit(ForStatementAST *ast);
+ virtual bool visit(FunctionDeclaratorAST *ast);
+ virtual bool visit(FunctionDefinitionAST *ast);
+ virtual bool visit(GotoStatementAST *ast);
+ virtual bool visit(IfStatementAST *ast);
+ virtual bool visit(LabeledStatementAST *ast);
+ virtual bool visit(LinkageBodyAST *ast);
+ virtual bool visit(LinkageSpecificationAST *ast);
+ virtual bool visit(MemInitializerAST *ast);
+ virtual bool visit(MemberAccessAST *ast);
+ virtual bool visit(NamedTypeSpecifierAST *ast);
+ virtual bool visit(NamespaceAST *ast);
+ virtual bool visit(NamespaceAliasDefinitionAST *ast);
+ virtual bool visit(NestedDeclaratorAST *ast);
+ virtual bool visit(NestedExpressionAST *ast);
+ virtual bool visit(NestedNameSpecifierAST *ast);
+ virtual bool visit(NewDeclaratorAST *ast);
+ virtual bool visit(NewExpressionAST *ast);
+ virtual bool visit(NewInitializerAST *ast);
+ virtual bool visit(NewTypeIdAST *ast);
+ virtual bool visit(NumericLiteralAST *ast);
+ virtual bool visit(OperatorAST *ast);
+ virtual bool visit(OperatorFunctionIdAST *ast);
+ virtual bool visit(ParameterDeclarationAST *ast);
+ virtual bool visit(ParameterDeclarationClauseAST *ast);
+ virtual bool visit(PointerAST *ast);
+ virtual bool visit(PointerToMemberAST *ast);
+ virtual bool visit(PostIncrDecrAST *ast);
+ virtual bool visit(PostfixExpressionAST *ast);
+ virtual bool visit(QualifiedNameAST *ast);
+ virtual bool visit(ReferenceAST *ast);
+ virtual bool visit(ReturnStatementAST *ast);
+ virtual bool visit(SimpleDeclarationAST *ast);
+ virtual bool visit(SimpleNameAST *ast);
+ virtual bool visit(SimpleSpecifierAST *ast);
+ virtual bool visit(SizeofExpressionAST *ast);
+ virtual bool visit(StringLiteralAST *ast);
+ virtual bool visit(SwitchStatementAST *ast);
+ virtual bool visit(TemplateArgumentListAST *ast);
+ virtual bool visit(TemplateDeclarationAST *ast);
+ virtual bool visit(TemplateIdAST *ast);
+ virtual bool visit(TemplateTypeParameterAST *ast);
+ virtual bool visit(ThisExpressionAST *ast);
+ virtual bool visit(ThrowExpressionAST *ast);
+ virtual bool visit(TranslationUnitAST *ast);
+ virtual bool visit(TryBlockStatementAST *ast);
+ virtual bool visit(TypeConstructorCallAST *ast);
+ virtual bool visit(TypeIdAST *ast);
+ virtual bool visit(TypeidExpressionAST *ast);
+ virtual bool visit(TypeofSpecifierAST *ast);
+ virtual bool visit(TypenameCallExpressionAST *ast);
+ virtual bool visit(TypenameTypeParameterAST *ast);
+ virtual bool visit(UnaryExpressionAST *ast);
+ virtual bool visit(UsingAST *ast);
+ virtual bool visit(UsingDirectiveAST *ast);
+ virtual bool visit(WhileStatementAST *ast);
+ virtual bool visit(QtMethodAST *ast);
+
+ void indent();
+ void deindent();
+ void newline();
+
+private:
+ std::ostream &out;
+ unsigned depth;
+};
+
+CPLUSPLUS_END_NAMESPACE
+CPLUSPLUS_END_HEADER
+
+#endif // CPLUSPLUS_PRETTYPRINTER_H
diff --git a/shared/cplusplus/cplusplus.pri b/shared/cplusplus/cplusplus.pri
index 2b3bb6804d..c3042948c1 100644
--- a/shared/cplusplus/cplusplus.pri
+++ b/shared/cplusplus/cplusplus.pri
@@ -35,7 +35,9 @@ HEADERS += \
$$PWD/Token.h \
$$PWD/TranslationUnit.h \
$$PWD/Type.h \
- $$PWD/TypeVisitor.h
+ $$PWD/TypeVisitor.h \
+ $$PWD/PrettyPrinter.h
+
SOURCES += \
$$PWD/AST.cpp \
@@ -69,5 +71,6 @@ SOURCES += \
$$PWD/Token.cpp \
$$PWD/TranslationUnit.cpp \
$$PWD/Type.cpp \
- $$PWD/TypeVisitor.cpp
+ $$PWD/TypeVisitor.cpp \
+ $$PWD/PrettyPrinter.cpp