Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add rpp files

  • Loading branch information...
commit ca86653c3e4980b65a3c3be8b2641b195241a39b 0 parents
@icefox authored
Showing with 18,669 additions and 0 deletions.
  1. +12 −0 README
  2. +19 −0 example/example.pro
  3. +5 −0 example/generator.qrc
  4. +146 −0 example/main.cpp
  5. +2 −0  rpp.pro
  6. +45 −0 src/ast.cpp
  7. +876 −0 src/ast.h
  8. +858 −0 src/binder.cpp
  9. +135 −0 src/binder.h
  10. +83 −0 src/class_compiler.cpp
  11. +82 −0 src/class_compiler.h
  12. +945 −0 src/codemodel.cpp
  13. +759 −0 src/codemodel.h
  14. +122 −0 src/codemodel_finder.cpp
  15. +87 −0 src/codemodel_finder.h
  16. +97 −0 src/codemodel_fwd.h
  17. +89 −0 src/codemodel_pointer.h
  18. +105 −0 src/codemodel_pointer_4.2.h
  19. +69 −0 src/compiler_utils.cpp
  20. +66 −0 src/compiler_utils.h
  21. +147 −0 src/control.cpp
  22. +152 −0 src/control.h
  23. +172 −0 src/declarator_compiler.cpp
  24. +100 −0 src/declarator_compiler.h
  25. +476 −0 src/default_visitor.cpp
  26. +135 −0 src/default_visitor.h
  27. +142 −0 src/dumptree.cpp
  28. +61 −0 src/dumptree.h
  29. +47 −0 src/include/stdarg.h
  30. +1,852 −0 src/lexer.cpp
  31. +298 −0 src/lexer.h
  32. +45 −0 src/list.cpp
  33. +119 −0 src/list.h
  34. +160 −0 src/name_compiler.cpp
  35. +78 −0 src/name_compiler.h
  36. +4,336 −0 src/parser.cpp
  37. +210 −0 src/parser.h
  38. +28 −0 src/r++.macros
  39. +25 −0 src/rpp-allocator.h
  40. +24 −0 src/rpp/builtin-macros.cpp
  41. +68 −0 src/rpp/pp-cctype.h
  42. +86 −0 src/rpp/pp-configuration
  43. +1,312 −0 src/rpp/pp-engine-bits.h
  44. +292 −0 src/rpp/pp-engine.h
  45. +162 −0 src/rpp/pp-environment.h
  46. +58 −0 src/rpp/pp-fwd.h
  47. +136 −0 src/rpp/pp-internal.h
  48. +95 −0 src/rpp/pp-iterator.h
  49. +401 −0 src/rpp/pp-macro-expander.h
  50. +92 −0 src/rpp/pp-macro.h
  51. +343 −0 src/rpp/pp-main.cpp
  52. +23 −0 src/rpp/pp-qt-configuration
  53. +370 −0 src/rpp/pp-scanner.h
  54. +116 −0 src/rpp/pp-string.h
  55. +99 −0 src/rpp/pp-symbol.h
  56. +110 −0 src/rpp/pp.h
  57. +179 −0 src/rpp/preprocessor.cpp
  58. +87 −0 src/rpp/preprocessor.h
  59. +20 −0 src/rpp/rpp.pri
  60. +48 −0 src/rxx.pri
  61. +12 −0 src/rxx.pro
  62. +131 −0 src/rxx_allocator.h
  63. +45 −0 src/smallobject.cpp
  64. +64 −0 src/smallobject.h
  65. +142 −0 src/symbol.h
  66. +271 −0 src/tokens.cpp
  67. +161 −0 src/tokens.h
  68. +156 −0 src/type_compiler.cpp
  69. +87 −0 src/type_compiler.h
  70. +137 −0 src/visitor.cpp
  71. +157 −0 src/visitor.h
12 README
@@ -0,0 +1,12 @@
+Roberto Raggi's C++ parser
+
+Obtained from the qtjambi-gpl-src-4.3.0_01.tar.gz package
+
+To Build:
+qmake -recursive
+make
+
+look in the examples directory for a simple example
+
+./example foo.cpp (just outputs any found classes and its functions)
+./example -E foo.cpp (outputs the preprocessed file)
19 example/example.pro
@@ -0,0 +1,19 @@
+TEMPLATE = app
+DEPENDPATH += .
+INCLUDEPATH += .
+
+unix:CONFIG += debug_and_release
+
+CONFIG += console
+RESOURCES += generator.qrc
+CONFIG += release
+
+win32: CONFIG += console
+mac:CONFIG -= app_bundle
+
+include(../src/rxx.pri)
+include(../src/rpp/rpp.pri)
+
+SOURCES += main.cpp
+
+QT = core
5 example/generator.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/trolltech/generator/">
+<file alias="pp-qt-configuration">../src/rpp/pp-qt-configuration</file>
+</qresource>
+</RCC>
146 example/main.cpp
@@ -0,0 +1,146 @@
+#include <QtCore>
+#include "pp.h"
+#include "parser.h"
+#include "control.h"
+#include "binder.h"
+
+static bool preprocess(const QString &sourceFile, QByteArray *out)
+{
+ rpp::pp_environment env;
+ rpp::pp preprocess(env);
+
+ rpp::pp_null_output_iterator null_out;
+
+ const char *ppconfig = ":/trolltech/generator/pp-qt-configuration";
+ QFile configFile(ppconfig);
+ if (!configFile.open(QFile::ReadOnly)) {
+ fprintf(stderr, "Preprocessor configuration file not found '%s'\n", ppconfig);
+ return false;
+ }
+
+ QByteArray ba = configFile.readAll();
+ configFile.close();
+ preprocess.operator() (ba.constData(), ba.constData() + ba.size(), null_out);
+
+ QString qtdir = getenv ("QTDIR");
+ if (qtdir.isEmpty()) {
+ fprintf(stderr, "Generator requires QTDIR to be set\n");
+ return false;
+ }
+
+ qtdir += "/include";
+
+ QString currentDir = QDir::current().absolutePath();
+ QFileInfo sourceInfo(sourceFile);
+ QDir::setCurrent(sourceInfo.absolutePath());
+
+ preprocess.push_include_path(".");
+ preprocess.push_include_path(QDir::convertSeparators(qtdir).toStdString());
+ preprocess.push_include_path(QDir::convertSeparators(qtdir + "/QtXml").toStdString());
+ preprocess.push_include_path(QDir::convertSeparators(qtdir + "/QtNetwork").toStdString());
+ preprocess.push_include_path(QDir::convertSeparators(qtdir + "/QtCore").toStdString());
+ preprocess.push_include_path(QDir::convertSeparators(qtdir + "/QtGui").toStdString());
+ preprocess.push_include_path(QDir::convertSeparators(qtdir + "/QtOpenGL").toStdString());
+
+ std::string result;
+ result.reserve (20 * 1024); // 20K
+
+ result += "# 1 \"builtins\"\n";
+ result += "# 1 \"";
+ result += sourceFile.toStdString();
+ result += "\"\n";
+
+ preprocess.file (sourceInfo.fileName().toStdString(),
+ rpp::pp_output_iterator<std::string> (result));
+
+ *out = QString::fromStdString(result).toUtf8();
+ return true;
+}
+
+QString convertAccessPolicy(CodeModel::AccessPolicy policy) {
+ switch(policy) {
+ case CodeModel::Public: return "public";
+ case CodeModel::Private: return "private";
+ case CodeModel::Protected: return "protected";
+ }
+ return QString();
+}
+
+QString makeFunction(FunctionModelItem function, const QString preFix = QString()) {
+ QString fullName;
+ fullName += function->type().toString();
+ fullName += " ";
+ fullName += preFix;
+ fullName += function->name();
+ ArgumentList arguments = function->arguments();
+ QStringList args;
+ for (int i = 0; i < arguments.count(); ++i) {
+ QString theargs = arguments[i]->type().toString() + " " + arguments[i]->name();
+ if (arguments[i]->defaultValue())
+ theargs += " = " + arguments[i]->defaultValueExpression();
+ args += theargs;
+ }
+ fullName += "(" + args.join(", ") + ")";
+ if (function->isConstant())
+ fullName += " const";
+ return fullName;
+}
+
+QStringList doneClasses;
+
+void outputFile(const QString &fileName, bool onlyPreprocess)
+{
+ QByteArray contents;
+ if (!preprocess(fileName, &contents)) {
+ QTextStream error(stderr);
+ error << "error preprocessing" << fileName;
+ return;
+ }
+
+ QTextStream out(stdout);
+ if (onlyPreprocess) {
+ out << contents;
+ return;
+ }
+
+ Control control;
+ Parser p(&control);
+ pool __pool;
+
+ TranslationUnitAST *ast = p.parse(contents, contents.size(), &__pool);
+
+ CodeModel model;
+ Binder binder(&model, p.location());
+ FileModelItem dom = binder.run(ast);
+
+ int i = 0;
+ for (i = 0; i < dom->classes().count(); ++i) {
+ QString name = dom->classes().at(i)->name();
+ if (doneClasses.contains(name))
+ continue;
+ out << dom->classes().at(i)->name() << endl;
+ doneClasses.append(name);
+ FunctionList functions = dom->classes().at(i)->functions();
+ for (int j = functions.count() - 1; j >= 0; --j) {
+ if (functions.at(j)->accessPolicy() != CodeModel::Private)
+ out << " " << makeFunction(functions.at(j)) << endl;
+ }
+ }
+}
+
+int main(int argc, char **argv)
+{
+ QString qtdir = getenv ("QTDIR");
+ if (qtdir.isEmpty()) {
+ fprintf(stderr, "Generator requires QTDIR to be set\n");
+ return 1;
+ }
+
+ if (argv[1][0] == '-' && argv[1][1] == 'E')
+ outputFile(argv[2], true);
+ else
+ outputFile(argv[1], false);
+
+ return 0;
+}
+
2  rpp.pro
@@ -0,0 +1,2 @@
+TEMPLATE = subdirs
+SUBDIRS = example
45 src/ast.cpp
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.
+**
+** This file is part of Qt Jambi.
+**
+** ** This file may be used under the terms of the GNU General Public
+** License version 2.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.trolltech.com/products/qt/opensource.html
+**
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://www.trolltech.com/products/qt/licensing.html or contact the
+** sales department at sales@trolltech.com.
+
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+/* This file is part of KDevelop
+ Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "ast.h"
+
+// kate: space-indent on; indent-width 2; replace-tabs on;
876 src/ast.h
@@ -0,0 +1,876 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.
+**
+** This file is part of Qt Jambi.
+**
+** ** This file may be used under the terms of the GNU General Public
+** License version 2.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.trolltech.com/products/qt/opensource.html
+**
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://www.trolltech.com/products/qt/licensing.html or contact the
+** sales department at sales@trolltech.com.
+
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+/* This file is part of KDevelop
+ Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef AST_H
+#define AST_H
+
+#include "smallobject.h"
+#include "list.h"
+
+#define DECLARE_AST_NODE(k) \
+ enum { __node_kind = Kind_##k };
+
+struct AccessSpecifierAST;
+struct AsmDefinitionAST;
+struct BaseClauseAST;
+struct BaseSpecifierAST;
+struct BinaryExpressionAST;
+struct CastExpressionAST;
+struct ClassMemberAccessAST;
+struct ClassSpecifierAST;
+struct CompoundStatementAST;
+struct ConditionAST;
+struct ConditionalExpressionAST;
+struct CppCastExpressionAST;
+struct CtorInitializerAST;
+struct DeclarationAST;
+struct DeclarationStatementAST;
+struct DeclaratorAST;
+struct DeleteExpressionAST;
+struct DoStatementAST;
+struct ElaboratedTypeSpecifierAST;
+struct EnumSpecifierAST;
+struct EnumeratorAST;
+struct ExceptionSpecificationAST;
+struct ExpressionAST;
+struct ExpressionOrDeclarationStatementAST;
+struct ExpressionStatementAST;
+struct ForStatementAST;
+struct FunctionCallAST;
+struct FunctionDefinitionAST;
+struct IfStatementAST;
+struct IncrDecrExpressionAST;
+struct InitDeclaratorAST;
+struct InitializerAST;
+struct InitializerClauseAST;
+struct LabeledStatementAST;
+struct LinkageBodyAST;
+struct LinkageSpecificationAST;
+struct MemInitializerAST;
+struct NameAST;
+struct NamespaceAST;
+struct NamespaceAliasDefinitionAST;
+struct NewDeclaratorAST;
+struct NewExpressionAST;
+struct NewInitializerAST;
+struct NewTypeIdAST;
+struct OperatorAST;
+struct OperatorFunctionIdAST;
+struct ParameterDeclarationAST;
+struct ParameterDeclarationClauseAST;
+struct PostfixExpressionAST;
+struct PrimaryExpressionAST;
+struct PtrOperatorAST;
+struct PtrToMemberAST;
+struct ReturnStatementAST;
+struct SimpleDeclarationAST;
+struct SimpleTypeSpecifierAST;
+struct SizeofExpressionAST;
+struct StatementAST;
+struct StringLiteralAST;
+struct SubscriptExpressionAST;
+struct SwitchStatementAST;
+struct TemplateArgumentAST;
+struct TemplateDeclarationAST;
+struct TemplateParameterAST;
+struct ThrowExpressionAST;
+struct TranslationUnitAST;
+struct TryBlockStatementAST;
+struct TypeIdAST;
+struct TypeIdentificationAST;
+struct TypeParameterAST;
+struct TypeSpecifierAST;
+struct TypedefAST;
+struct UnaryExpressionAST;
+struct UnqualifiedNameAST;
+struct UsingAST;
+struct UsingDirectiveAST;
+struct WhileStatementAST;
+struct WinDeclSpecAST;
+struct QPropertyAST;
+
+struct AST
+{
+ enum NODE_KIND
+ {
+ Kind_UNKNOWN = 0,
+
+ Kind_AccessSpecifier,
+ Kind_AsmDefinition,
+ Kind_BaseClause,
+ Kind_BaseSpecifier,
+ Kind_BinaryExpression,
+ Kind_CastExpression,
+ Kind_ClassMemberAccess,
+ Kind_ClassSpecifier,
+ Kind_CompoundStatement,
+ Kind_Condition,
+ Kind_ConditionalExpression,
+ Kind_CppCastExpression,
+ Kind_CtorInitializer,
+ Kind_DeclarationStatement,
+ Kind_Declarator,
+ Kind_DeleteExpression,
+ Kind_DoStatement,
+ Kind_ElaboratedTypeSpecifier,
+ Kind_EnumSpecifier,
+ Kind_Enumerator,
+ Kind_ExceptionSpecification,
+ Kind_ExpressionOrDeclarationStatement,
+ Kind_ExpressionStatement,
+ Kind_ForStatement,
+ Kind_FunctionCall,
+ Kind_FunctionDefinition,
+ Kind_IfStatement,
+ Kind_IncrDecrExpression,
+ Kind_InitDeclarator,
+ Kind_Initializer,
+ Kind_InitializerClause,
+ Kind_LabeledStatement,
+ Kind_LinkageBody,
+ Kind_LinkageSpecification,
+ Kind_MemInitializer,
+ Kind_Name,
+ Kind_Namespace,
+ Kind_NamespaceAliasDefinition,
+ Kind_NewDeclarator,
+ Kind_NewExpression,
+ Kind_NewInitializer,
+ Kind_NewTypeId,
+ Kind_Operator,
+ Kind_OperatorFunctionId,
+ Kind_ParameterDeclaration,
+ Kind_ParameterDeclarationClause,
+ Kind_PostfixExpression,
+ Kind_PrimaryExpression,
+ Kind_PtrOperator,
+ Kind_PtrToMember,
+ Kind_ReturnStatement,
+ Kind_SimpleDeclaration,
+ Kind_SimpleTypeSpecifier,
+ Kind_SizeofExpression,
+ Kind_StringLiteral,
+ Kind_SubscriptExpression,
+ Kind_SwitchStatement,
+ Kind_TemplateArgument,
+ Kind_TemplateDeclaration,
+ Kind_TemplateParameter,
+ Kind_ThrowExpression,
+ Kind_TranslationUnit,
+ Kind_TryBlockStatement,
+ Kind_TypeId,
+ Kind_TypeIdentification,
+ Kind_TypeParameter,
+ Kind_Typedef,
+ Kind_UnaryExpression,
+ Kind_UnqualifiedName,
+ Kind_Using,
+ Kind_UsingDirective,
+ Kind_WhileStatement,
+ Kind_WinDeclSpec,
+ Kind_QPropertyAST,
+
+ NODE_KIND_COUNT
+ };
+
+ int kind;
+
+ std::size_t start_token;
+ std::size_t end_token;
+};
+
+struct TypeSpecifierAST: public AST
+{
+ const ListNode<std::size_t> *cv;
+};
+
+struct StatementAST: public AST
+{
+};
+
+struct ExpressionAST: public AST
+{
+};
+
+struct DeclarationAST: public AST
+{
+};
+
+struct AccessSpecifierAST: public DeclarationAST
+{
+ DECLARE_AST_NODE(AccessSpecifier)
+
+ const ListNode<std::size_t> *specs;
+};
+
+struct AsmDefinitionAST: public DeclarationAST
+{
+ DECLARE_AST_NODE(AsmDefinition)
+
+ const ListNode<std::size_t> *cv;
+};
+
+struct BaseClauseAST: public AST // ### kill me
+{
+ DECLARE_AST_NODE(BaseClause)
+
+ const ListNode<BaseSpecifierAST*> *base_specifiers;
+};
+
+struct BaseSpecifierAST: public AST
+{
+ DECLARE_AST_NODE(BaseSpecifier)
+
+ std::size_t virt;
+ std::size_t access_specifier;
+ NameAST *name;
+};
+
+struct BinaryExpressionAST: public ExpressionAST
+{
+ DECLARE_AST_NODE(BinaryExpression)
+
+ std::size_t op;
+ ExpressionAST *left_expression;
+ ExpressionAST *right_expression;
+};
+
+struct CastExpressionAST: public ExpressionAST
+{
+ DECLARE_AST_NODE(CastExpression)
+
+ TypeIdAST *type_id;
+ ExpressionAST *expression;
+};
+
+struct ClassMemberAccessAST: public ExpressionAST
+{
+ DECLARE_AST_NODE(ClassMemberAccess)
+
+ std::size_t op;
+ NameAST *name;
+};
+
+struct ClassSpecifierAST: public TypeSpecifierAST
+{
+ DECLARE_AST_NODE(ClassSpecifier)
+
+ WinDeclSpecAST *win_decl_specifiers;
+ std::size_t class_key;
+ NameAST *name;
+ BaseClauseAST *base_clause;
+ const ListNode<DeclarationAST*> *member_specs;
+};
+
+struct CompoundStatementAST: public StatementAST
+{
+ DECLARE_AST_NODE(CompoundStatement)
+
+ const ListNode<StatementAST*> *statements;
+};
+
+struct ConditionAST: public AST
+{
+ DECLARE_AST_NODE(Condition)
+
+ TypeSpecifierAST *type_specifier;
+ DeclaratorAST *declarator;
+ ExpressionAST *expression;
+};
+
+struct ConditionalExpressionAST: public ExpressionAST
+{
+ DECLARE_AST_NODE(ConditionalExpression)
+
+ ExpressionAST *condition;
+ ExpressionAST *left_expression;
+ ExpressionAST *right_expression;
+};
+
+struct CppCastExpressionAST: public ExpressionAST
+{
+ DECLARE_AST_NODE(CppCastExpression)
+
+ std::size_t op;
+ TypeIdAST *type_id;
+ ExpressionAST *expression;
+ const ListNode<ExpressionAST*> *sub_expressions;
+};
+
+struct CtorInitializerAST: public AST
+{
+ DECLARE_AST_NODE(CtorInitializer)
+
+ std::size_t colon;
+ const ListNode<MemInitializerAST*> *member_initializers;
+};
+
+struct DeclarationStatementAST: public StatementAST
+{
+ DECLARE_AST_NODE(DeclarationStatement)
+
+ DeclarationAST *declaration;
+};
+
+struct DeclaratorAST: public AST
+{
+ DECLARE_AST_NODE(Declarator)
+
+ const ListNode<PtrOperatorAST*> *ptr_ops;
+ DeclaratorAST *sub_declarator;
+ NameAST *id;
+ ExpressionAST *bit_expression;
+ const ListNode<ExpressionAST*> *array_dimensions;
+ ParameterDeclarationClauseAST *parameter_declaration_clause;
+ const ListNode<std::size_t> *fun_cv;
+ ExceptionSpecificationAST *exception_spec;
+};
+
+struct DeleteExpressionAST: public ExpressionAST
+{
+ DECLARE_AST_NODE(DeleteExpression)
+
+ std::size_t scope_token;
+ std::size_t delete_token;
+ std::size_t lbracket_token;
+ std::size_t rbracket_token;
+ ExpressionAST *expression;
+};
+
+struct DoStatementAST: public StatementAST
+{
+ DECLARE_AST_NODE(DoStatement)
+
+ StatementAST *statement;
+ ExpressionAST *expression;
+};
+
+struct ElaboratedTypeSpecifierAST: public TypeSpecifierAST
+{
+ DECLARE_AST_NODE(ElaboratedTypeSpecifier)
+
+ std::size_t type;
+ NameAST *name;
+};
+
+struct EnumSpecifierAST: public TypeSpecifierAST
+{
+ DECLARE_AST_NODE(EnumSpecifier)
+
+ NameAST *name;
+ const ListNode<EnumeratorAST*> *enumerators;
+};
+
+struct EnumeratorAST: public AST
+{
+ DECLARE_AST_NODE(Enumerator)
+
+ std::size_t id;
+ ExpressionAST *expression;
+};
+
+struct ExceptionSpecificationAST: public AST
+{
+ DECLARE_AST_NODE(ExceptionSpecification)
+
+ std::size_t ellipsis;
+ const ListNode<TypeIdAST*> *type_ids;
+};
+
+struct ExpressionOrDeclarationStatementAST: public StatementAST
+{
+ DECLARE_AST_NODE(ExpressionOrDeclarationStatement)
+
+ StatementAST *expression;
+ StatementAST *declaration;
+};
+
+struct ExpressionStatementAST: public StatementAST
+{
+ DECLARE_AST_NODE(ExpressionStatement)
+
+ ExpressionAST *expression;
+};
+
+struct FunctionCallAST: public ExpressionAST
+{
+ DECLARE_AST_NODE(FunctionCall)
+
+ ExpressionAST *arguments;
+};
+
+struct FunctionDefinitionAST: public DeclarationAST
+{
+ DECLARE_AST_NODE(FunctionDefinition)
+
+ const ListNode<std::size_t> *storage_specifiers;
+ const ListNode<std::size_t> *function_specifiers;
+ TypeSpecifierAST *type_specifier;
+ InitDeclaratorAST *init_declarator;
+ StatementAST *function_body;
+ WinDeclSpecAST *win_decl_specifiers;
+};
+
+struct ForStatementAST: public StatementAST
+{
+ DECLARE_AST_NODE(ForStatement)
+
+ StatementAST *init_statement;
+ ConditionAST *condition;
+ ExpressionAST *expression;
+ StatementAST *statement;
+};
+
+struct IfStatementAST: public StatementAST
+{
+ DECLARE_AST_NODE(IfStatement)
+
+ ConditionAST *condition;
+ StatementAST *statement;
+ StatementAST *else_statement;
+};
+
+struct IncrDecrExpressionAST: public ExpressionAST
+{
+ DECLARE_AST_NODE(IncrDecrExpression)
+
+ std::size_t op;
+};
+
+struct InitDeclaratorAST: public AST
+{
+ DECLARE_AST_NODE(InitDeclarator)
+
+ DeclaratorAST *declarator;
+ InitializerAST *initializer;
+};
+
+struct InitializerAST: public AST
+{
+ DECLARE_AST_NODE(Initializer)
+
+ InitializerClauseAST *initializer_clause;
+ ExpressionAST *expression;
+};
+
+struct InitializerClauseAST: public AST
+{
+ DECLARE_AST_NODE(InitializerClause)
+
+ ExpressionAST *expression;
+};
+
+struct LabeledStatementAST: public StatementAST
+{
+ DECLARE_AST_NODE(LabeledStatement)
+};
+
+struct LinkageBodyAST: public AST
+{
+ DECLARE_AST_NODE(LinkageBody)
+
+ const ListNode<DeclarationAST*> *declarations;
+};
+
+struct LinkageSpecificationAST: public DeclarationAST
+{
+ DECLARE_AST_NODE(LinkageSpecification)
+
+ std::size_t extern_type;
+ LinkageBodyAST *linkage_body;
+ DeclarationAST *declaration;
+};
+
+struct MemInitializerAST: public AST
+{
+ DECLARE_AST_NODE(MemInitializer)
+
+ NameAST *initializer_id;
+ ExpressionAST *expression;
+};
+
+struct NameAST: public AST
+{
+ DECLARE_AST_NODE(Name)
+
+ bool global;
+ const ListNode<UnqualifiedNameAST*> *qualified_names;
+ UnqualifiedNameAST *unqualified_name;
+};
+
+struct NamespaceAST: public DeclarationAST
+{
+ DECLARE_AST_NODE(Namespace)
+
+ std::size_t namespace_name;
+ LinkageBodyAST *linkage_body;
+};
+
+struct NamespaceAliasDefinitionAST: public DeclarationAST
+{
+ DECLARE_AST_NODE(NamespaceAliasDefinition)
+
+ std::size_t namespace_name;
+ NameAST *alias_name;
+};
+
+struct NewDeclaratorAST: public AST
+{
+ DECLARE_AST_NODE(NewDeclarator)
+
+ PtrOperatorAST *ptr_op;
+ NewDeclaratorAST *sub_declarator;
+ const ListNode<ExpressionAST*> *expressions;
+};
+
+struct NewExpressionAST: public ExpressionAST
+{
+ DECLARE_AST_NODE(NewExpression)
+
+ std::size_t scope_token;
+ std::size_t new_token;
+ ExpressionAST *expression;
+ TypeIdAST *type_id;
+ NewTypeIdAST *new_type_id;
+ NewInitializerAST *new_initializer;
+};
+
+struct NewInitializerAST: public AST
+{
+ DECLARE_AST_NODE(NewInitializer)
+
+ ExpressionAST *expression;
+};
+
+struct NewTypeIdAST: public AST
+{
+ DECLARE_AST_NODE(NewTypeId)
+
+ TypeSpecifierAST *type_specifier;
+ NewInitializerAST *new_initializer;
+ NewDeclaratorAST *new_declarator;
+};
+
+struct OperatorAST: public AST
+{
+ DECLARE_AST_NODE(Operator)
+
+ std::size_t op;
+ std::size_t open;
+ std::size_t close;
+};
+
+struct OperatorFunctionIdAST: public AST
+{
+ DECLARE_AST_NODE(OperatorFunctionId)
+
+ OperatorAST *op;
+ TypeSpecifierAST *type_specifier;
+ const ListNode<PtrOperatorAST*> *ptr_ops;
+};
+
+struct ParameterDeclarationAST: public AST
+{
+ DECLARE_AST_NODE(ParameterDeclaration)
+
+ TypeSpecifierAST *type_specifier;
+ DeclaratorAST *declarator;
+ ExpressionAST *expression;
+};
+
+struct ParameterDeclarationClauseAST: public AST
+{
+ DECLARE_AST_NODE(ParameterDeclarationClause)
+
+ const ListNode<ParameterDeclarationAST*> *parameter_declarations;
+ std::size_t ellipsis;
+};
+
+struct PostfixExpressionAST: public ExpressionAST
+{
+ DECLARE_AST_NODE(PostfixExpression)
+
+ TypeSpecifierAST *type_specifier;
+ ExpressionAST *expression;
+ const ListNode<ExpressionAST*> *sub_expressions;
+};
+
+struct PrimaryExpressionAST: public ExpressionAST
+{
+ DECLARE_AST_NODE(PrimaryExpression)
+
+ StringLiteralAST *literal;
+ std::size_t token;
+ StatementAST *expression_statement;
+ ExpressionAST *sub_expression;
+ NameAST *name;
+};
+
+struct PtrOperatorAST: public AST
+{
+ DECLARE_AST_NODE(PtrOperator)
+
+ const ListNode<std::size_t> *cv;
+ std::size_t op;
+ PtrToMemberAST *mem_ptr;
+};
+
+struct PtrToMemberAST: public AST
+{
+ DECLARE_AST_NODE(PtrToMember)
+};
+
+struct ReturnStatementAST: public StatementAST
+{
+ DECLARE_AST_NODE(ReturnStatement)
+
+ ExpressionAST *expression;
+};
+
+struct SimpleDeclarationAST: public DeclarationAST
+{
+ DECLARE_AST_NODE(SimpleDeclaration)
+
+ const ListNode<std::size_t> *storage_specifiers;
+ const ListNode<std::size_t> *function_specifiers;
+ TypeSpecifierAST *type_specifier;
+ const ListNode<InitDeclaratorAST*> *init_declarators;
+ WinDeclSpecAST *win_decl_specifiers;
+};
+
+struct SimpleTypeSpecifierAST: public TypeSpecifierAST
+{
+ DECLARE_AST_NODE(SimpleTypeSpecifier)
+
+ const ListNode<std::size_t> *integrals;
+ std::size_t type_of;
+ TypeIdAST *type_id;
+ ExpressionAST *expression;
+ NameAST *name;
+};
+
+struct SizeofExpressionAST: public ExpressionAST
+{
+ DECLARE_AST_NODE(SizeofExpression)
+
+ std::size_t sizeof_token;
+ TypeIdAST *type_id;
+ ExpressionAST *expression;
+};
+
+struct StringLiteralAST: public AST
+{
+ DECLARE_AST_NODE(StringLiteral)
+
+ const ListNode<std::size_t> *literals;
+};
+
+struct SubscriptExpressionAST: public ExpressionAST
+{
+ DECLARE_AST_NODE(SubscriptExpression)
+
+ ExpressionAST *subscript;
+};
+
+struct SwitchStatementAST: public StatementAST
+{
+ DECLARE_AST_NODE(SwitchStatement)
+
+ ConditionAST *condition;
+ StatementAST *statement;
+};
+
+struct TemplateArgumentAST: public AST
+{
+ DECLARE_AST_NODE(TemplateArgument)
+
+ TypeIdAST *type_id;
+ ExpressionAST *expression;
+};
+
+struct TemplateDeclarationAST: public DeclarationAST
+{
+ DECLARE_AST_NODE(TemplateDeclaration)
+
+ std::size_t exported;
+ const ListNode<TemplateParameterAST*> *template_parameters;
+ DeclarationAST* declaration;
+};
+
+struct TemplateParameterAST: public AST
+{
+ DECLARE_AST_NODE(TemplateParameter)
+
+ TypeParameterAST *type_parameter;
+ ParameterDeclarationAST *parameter_declaration;
+};
+
+struct ThrowExpressionAST: public ExpressionAST
+{
+ DECLARE_AST_NODE(ThrowExpression)
+
+ std::size_t throw_token;
+ ExpressionAST *expression;
+};
+
+struct TranslationUnitAST: public AST
+{
+ DECLARE_AST_NODE(TranslationUnit)
+
+ const ListNode<DeclarationAST*> *declarations;
+};
+
+struct TryBlockStatementAST: public StatementAST
+{
+ DECLARE_AST_NODE(TryBlockStatement)
+};
+
+struct TypeIdAST: public AST
+{
+ DECLARE_AST_NODE(TypeId)
+
+ TypeSpecifierAST *type_specifier;
+ DeclaratorAST *declarator;
+};
+
+struct TypeIdentificationAST: public ExpressionAST
+{
+ DECLARE_AST_NODE(TypeIdentification)
+
+ std::size_t typename_token;
+ NameAST *name;
+ ExpressionAST *expression;
+};
+
+struct TypeParameterAST: public AST
+{
+ DECLARE_AST_NODE(TypeParameter)
+
+ std::size_t type;
+ NameAST *name;
+ TypeIdAST *type_id;
+ const ListNode<TemplateParameterAST*> *template_parameters;
+ NameAST *template_name;
+};
+
+struct TypedefAST: public DeclarationAST
+{
+ DECLARE_AST_NODE(Typedef)
+
+ TypeSpecifierAST *type_specifier;
+ const ListNode<InitDeclaratorAST*> *init_declarators;
+};
+
+struct UnaryExpressionAST: public ExpressionAST
+{
+ DECLARE_AST_NODE(UnaryExpression)
+
+ std::size_t op;
+ ExpressionAST *expression;
+};
+
+struct UnqualifiedNameAST: public AST
+{
+ DECLARE_AST_NODE(UnqualifiedName)
+
+ std::size_t tilde;
+ std::size_t id;
+ OperatorFunctionIdAST *operator_id;
+ const ListNode<TemplateArgumentAST*> *template_arguments;
+};
+
+struct UsingAST: public DeclarationAST
+{
+ DECLARE_AST_NODE(Using)
+
+ std::size_t type_name;
+ NameAST *name;
+};
+
+struct UsingDirectiveAST: public DeclarationAST
+{
+ DECLARE_AST_NODE(UsingDirective)
+
+ NameAST *name;
+};
+
+struct WhileStatementAST: public StatementAST
+{
+ DECLARE_AST_NODE(WhileStatement)
+
+ ConditionAST *condition;
+ StatementAST *statement;
+};
+
+struct WinDeclSpecAST: public AST
+{
+ DECLARE_AST_NODE(WinDeclSpec)
+
+ std::size_t specifier;
+ std::size_t modifier;
+};
+
+struct QPropertyAST : public DeclarationAST
+{
+ DECLARE_AST_NODE(QPropertyAST)
+};
+
+template <class _Tp>
+_Tp *CreateNode(pool *memory_pool)
+{
+ _Tp *node = reinterpret_cast<_Tp*>(memory_pool->allocate(sizeof(_Tp)));
+ node->kind = _Tp::__node_kind;
+ return node;
+}
+
+template <class _Tp>
+_Tp ast_cast(AST *item)
+{
+ if (item && static_cast<_Tp>(0)->__node_kind == item->kind)
+ return static_cast<_Tp>(item);
+
+ return 0;
+}
+
+#endif // AST_H
+
+// kate: space-indent on; indent-width 2; replace-tabs on;
858 src/binder.cpp
@@ -0,0 +1,858 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.
+**
+** This file is part of Qt Jambi.
+**
+** ** This file may be used under the terms of the GNU General Public
+** License version 2.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.trolltech.com/products/qt/opensource.html
+**
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://www.trolltech.com/products/qt/licensing.html or contact the
+** sales department at sales@trolltech.com.
+
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+
+/* This file is part of KDevelop
+ Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org>
+ Copyright (C) 2005 Trolltech AS
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "binder.h"
+#include "lexer.h"
+#include "control.h"
+#include "symbol.h"
+#include "codemodel_finder.h"
+#include "class_compiler.h"
+#include "compiler_utils.h"
+#include "tokens.h"
+#include "dumptree.h"
+
+#include <iostream>
+
+#include <qdebug.h>
+
+Binder::Binder(CodeModel *__model, LocationManager &__location, Control *__control)
+ : _M_model(__model),
+ _M_location(__location),
+ _M_token_stream(&_M_location.token_stream),
+ _M_control(__control),
+ _M_current_function_type(CodeModel::Normal),
+ type_cc(this),
+ name_cc(this),
+ decl_cc(this)
+{
+ _M_qualified_types["char"] = QString();
+ _M_qualified_types["double"] = QString();
+ _M_qualified_types["float"] = QString();
+ _M_qualified_types["int"] = QString();
+ _M_qualified_types["long"] = QString();
+ _M_qualified_types["short"] = QString();
+ _M_qualified_types["void"] = QString();
+}
+
+Binder::~Binder()
+{
+}
+
+FileModelItem Binder::run(AST *node)
+{
+ FileModelItem old = _M_current_file;
+ _M_current_access = CodeModel::Public;
+
+ _M_current_file = model()->create<FileModelItem>();
+ updateItemPosition (_M_current_file->toItem(), node);
+ visit(node);
+ FileModelItem result = _M_current_file;
+
+ _M_current_file = old; // restore
+
+ return result;
+}
+
+ScopeModelItem Binder::currentScope()
+{
+ if (_M_current_class)
+ return model_static_cast<ScopeModelItem>(_M_current_class);
+ else if (_M_current_namespace)
+ return model_static_cast<ScopeModelItem>(_M_current_namespace);
+
+ return model_static_cast<ScopeModelItem>(_M_current_file);
+}
+
+TemplateParameterList Binder::changeTemplateParameters(TemplateParameterList templateParameters)
+{
+ TemplateParameterList old = _M_current_template_parameters;
+ _M_current_template_parameters = templateParameters;
+ return old;
+}
+
+CodeModel::FunctionType Binder::changeCurrentFunctionType(CodeModel::FunctionType functionType)
+{
+ CodeModel::FunctionType old = _M_current_function_type;
+ _M_current_function_type = functionType;
+ return old;
+}
+
+CodeModel::AccessPolicy Binder::changeCurrentAccess(CodeModel::AccessPolicy accessPolicy)
+{
+ CodeModel::AccessPolicy old = _M_current_access;
+ _M_current_access = accessPolicy;
+ return old;
+}
+
+NamespaceModelItem Binder::changeCurrentNamespace(NamespaceModelItem item)
+{
+ NamespaceModelItem old = _M_current_namespace;
+ _M_current_namespace = item;
+ return old;
+}
+
+ClassModelItem Binder::changeCurrentClass(ClassModelItem item)
+{
+ ClassModelItem old = _M_current_class;
+ _M_current_class = item;
+ return old;
+}
+
+FunctionDefinitionModelItem Binder::changeCurrentFunction(FunctionDefinitionModelItem item)
+{
+ FunctionDefinitionModelItem old = _M_current_function;
+ _M_current_function = item;
+ return old;
+}
+
+int Binder::decode_token(std::size_t index) const
+{
+ return _M_token_stream->kind(index);
+}
+
+CodeModel::AccessPolicy Binder::decode_access_policy(std::size_t index) const
+{
+ switch (decode_token(index))
+ {
+ case Token_class:
+ return CodeModel::Private;
+
+ case Token_struct:
+ case Token_union:
+ return CodeModel::Public;
+
+ default:
+ return CodeModel::Public;
+ }
+}
+
+CodeModel::ClassType Binder::decode_class_type(std::size_t index) const
+{
+ switch (decode_token(index))
+ {
+ case Token_class:
+ return CodeModel::Class;
+ case Token_struct:
+ return CodeModel::Struct;
+ case Token_union:
+ return CodeModel::Union;
+ default:
+ std::cerr << "** WARNING unrecognized class type" << std::endl;
+ }
+ return CodeModel::Class;
+}
+
+const NameSymbol *Binder::decode_symbol(std::size_t index) const
+{
+ return _M_token_stream->symbol(index);
+}
+
+void Binder::visitAccessSpecifier(AccessSpecifierAST *node)
+{
+ const ListNode<std::size_t> *it = node->specs;
+ if (it == 0)
+ return;
+
+ it = it->toFront();
+ const ListNode<std::size_t> *end = it;
+
+ do
+ {
+ switch (decode_token(it->element))
+ {
+ default:
+ break;
+
+ case Token_public:
+ changeCurrentAccess(CodeModel::Public);
+ changeCurrentFunctionType(CodeModel::Normal);
+ break;
+ case Token_protected:
+ changeCurrentAccess(CodeModel::Protected);
+ changeCurrentFunctionType(CodeModel::Normal);
+ break;
+ case Token_private:
+ changeCurrentAccess(CodeModel::Private);
+ changeCurrentFunctionType(CodeModel::Normal);
+ break;
+ case Token_signals:
+ changeCurrentAccess(CodeModel::Protected);
+ changeCurrentFunctionType(CodeModel::Signal);
+ break;
+ case Token_slots:
+ changeCurrentFunctionType(CodeModel::Slot);
+ break;
+ }
+ it = it->next;
+ }
+ while (it != end);
+}
+
+void Binder::visitSimpleDeclaration(SimpleDeclarationAST *node)
+{
+ visit(node->type_specifier);
+
+ if (const ListNode<InitDeclaratorAST*> *it = node->init_declarators)
+ {
+ it = it->toFront();
+ const ListNode<InitDeclaratorAST*> *end = it;
+ do
+ {
+ InitDeclaratorAST *init_declarator = it->element;
+ declare_symbol(node, init_declarator);
+ it = it->next;
+ }
+ while (it != end);
+ }
+}
+
+void Binder::declare_symbol(SimpleDeclarationAST *node, InitDeclaratorAST *init_declarator)
+{
+ DeclaratorAST *declarator = init_declarator->declarator;
+
+ while (declarator && declarator->sub_declarator)
+ declarator = declarator->sub_declarator;
+
+ NameAST *id = declarator->id;
+ if (! declarator->id)
+ {
+ std::cerr << "** WARNING expected a declarator id" << std::endl;
+ return;
+ }
+
+ CodeModelFinder finder(model(), this);
+ ScopeModelItem symbolScope = finder.resolveScope(id, currentScope());
+ if (! symbolScope)
+ {
+ name_cc.run(id);
+ std::cerr << "** WARNING scope not found for symbol:"
+ << qPrintable(name_cc.name()) << std::endl;
+ return;
+ }
+
+ decl_cc.run(declarator);
+
+ if (decl_cc.isFunction())
+ {
+ name_cc.run(id->unqualified_name);
+
+ FunctionModelItem fun = model()->create<FunctionModelItem>();
+ updateItemPosition (fun->toItem(), node);
+ fun->setAccessPolicy(_M_current_access);
+ fun->setFunctionType(_M_current_function_type);
+ fun->setName(name_cc.name());
+ fun->setAbstract(init_declarator->initializer != 0);
+ fun->setConstant(declarator->fun_cv != 0);
+ fun->setTemplateParameters(_M_current_template_parameters);
+ applyStorageSpecifiers(node->storage_specifiers, model_static_cast<MemberModelItem>(fun));
+ applyFunctionSpecifiers(node->function_specifiers, fun);
+
+ // build the type
+ TypeInfo typeInfo = CompilerUtils::typeDescription(node->type_specifier,
+ declarator,
+ this);
+
+ fun->setType(qualifyType(typeInfo, symbolScope->qualifiedName()));
+
+
+ fun->setVariadics (decl_cc.isVariadics ());
+
+ // ... and the signature
+ foreach (DeclaratorCompiler::Parameter p, decl_cc.parameters())
+ {
+ ArgumentModelItem arg = model()->create<ArgumentModelItem>();
+ arg->setType(qualifyType(p.type, _M_context));
+ arg->setName(p.name);
+ arg->setDefaultValue(p.defaultValue);
+ if (p.defaultValue)
+ arg->setDefaultValueExpression(p.defaultValueExpression);
+ fun->addArgument(arg);
+ }
+
+ fun->setScope(symbolScope->qualifiedName());
+ symbolScope->addFunction(fun);
+ }
+ else
+ {
+ VariableModelItem var = model()->create<VariableModelItem>();
+ updateItemPosition (var->toItem(), node);
+ var->setTemplateParameters(_M_current_template_parameters);
+ var->setAccessPolicy(_M_current_access);
+ name_cc.run(id->unqualified_name);
+ var->setName(name_cc.name());
+ TypeInfo typeInfo = CompilerUtils::typeDescription(node->type_specifier,
+ declarator,
+ this);
+ if (declarator != init_declarator->declarator
+ && init_declarator->declarator->parameter_declaration_clause != 0)
+ {
+ typeInfo.setFunctionPointer (true);
+ decl_cc.run (init_declarator->declarator);
+ foreach (DeclaratorCompiler::Parameter p, decl_cc.parameters())
+ typeInfo.addArgument(p.type);
+ }
+
+ var->setType(qualifyType(typeInfo, _M_context));
+ applyStorageSpecifiers(node->storage_specifiers, model_static_cast<MemberModelItem>(var));
+
+ var->setScope(symbolScope->qualifiedName());
+ symbolScope->addVariable(var);
+ }
+}
+
+void Binder::visitFunctionDefinition(FunctionDefinitionAST *node)
+{
+ Q_ASSERT(node->init_declarator != 0);
+
+ ScopeModelItem scope = currentScope();
+
+ InitDeclaratorAST *init_declarator = node->init_declarator;
+ DeclaratorAST *declarator = init_declarator->declarator;
+
+ CodeModelFinder finder(model(), this);
+
+ ScopeModelItem functionScope = finder.resolveScope(declarator->id, scope);
+ if (! functionScope)
+ {
+ name_cc.run(declarator->id);
+ std::cerr << "** WARNING scope not found for function definition:"
+ << qPrintable(name_cc.name()) << std::endl
+ << "\tdefinition *ignored*"
+ << std::endl;
+ return;
+ }
+
+ decl_cc.run(declarator);
+
+ Q_ASSERT(! decl_cc.id().isEmpty());
+
+ FunctionDefinitionModelItem
+ old = changeCurrentFunction(_M_model->create<FunctionDefinitionModelItem>());
+ _M_current_function->setScope(functionScope->qualifiedName());
+ updateItemPosition (_M_current_function->toItem(), node);
+
+ Q_ASSERT(declarator->id->unqualified_name != 0);
+ name_cc.run(declarator->id->unqualified_name);
+ QString unqualified_name = name_cc.name();
+
+ _M_current_function->setName(unqualified_name);
+ TypeInfo tmp_type = CompilerUtils::typeDescription(node->type_specifier,
+ declarator, this);
+
+ _M_current_function->setType(qualifyType(tmp_type, _M_context));
+ _M_current_function->setAccessPolicy(_M_current_access);
+ _M_current_function->setFunctionType(_M_current_function_type);
+ _M_current_function->setConstant(declarator->fun_cv != 0);
+ _M_current_function->setTemplateParameters(_M_current_template_parameters);
+
+ applyStorageSpecifiers(node->storage_specifiers,
+ model_static_cast<MemberModelItem>(_M_current_function));
+ applyFunctionSpecifiers(node->function_specifiers,
+ model_static_cast<FunctionModelItem>(_M_current_function));
+
+ _M_current_function->setVariadics (decl_cc.isVariadics ());
+
+ foreach (DeclaratorCompiler::Parameter p, decl_cc.parameters())
+ {
+ ArgumentModelItem arg = model()->create<ArgumentModelItem>();
+ arg->setType(qualifyType(p.type, functionScope->qualifiedName()));
+ arg->setName(p.name);
+ arg->setDefaultValue(p.defaultValue);
+ if (p.defaultValue)
+ arg->setDefaultValueExpression(p.defaultValueExpression);
+ _M_current_function->addArgument(arg);
+ }
+
+ functionScope->addFunctionDefinition(_M_current_function);
+
+ FunctionModelItem prototype = model_static_cast<FunctionModelItem>(_M_current_function);
+ FunctionModelItem declared = functionScope->declaredFunction(prototype);
+
+ // try to find a function declaration for this definition..
+ if (! declared)
+ {
+ functionScope->addFunction(prototype);
+ }
+ else
+ {
+ applyFunctionSpecifiers(node->function_specifiers, declared);
+
+ // fix the function type and the access policy
+ _M_current_function->setAccessPolicy(declared->accessPolicy());
+ _M_current_function->setFunctionType(declared->functionType());
+ }
+
+ changeCurrentFunction(old);
+}
+
+void Binder::visitTemplateDeclaration(TemplateDeclarationAST *node)
+{
+ const ListNode<TemplateParameterAST*> *it = node->template_parameters;
+ if (it == 0)
+ return;
+
+ TemplateParameterList savedTemplateParameters = changeTemplateParameters(TemplateParameterList());
+
+ it = it->toFront();
+ const ListNode<TemplateParameterAST*> *end = it;
+
+ TemplateParameterList templateParameters;
+ do
+ {
+ TemplateParameterAST *parameter = it->element;
+ TypeParameterAST *type_parameter = parameter->type_parameter;
+ if (! type_parameter)
+ {
+// std::cerr << "** WARNING template declaration not supported ``";
+// Token const &tk = _M_token_stream->token ((int) node->start_token);
+// Token const &end_tk = _M_token_stream->token ((int) node->declaration->start_token);
+
+// std::cerr << std::string (&tk.text[tk.position], (end_tk.position) - tk.position) << "''"
+// << std::endl << std::endl;
+
+ changeTemplateParameters(savedTemplateParameters);
+ return;
+ }
+ assert(type_parameter != 0);
+
+ TemplateParameterModelItem p = model()->create<TemplateParameterModelItem>();
+ int tk = decode_token(type_parameter->type);
+ if (tk != Token_typename && tk != Token_class)
+ {
+// std::cerr << "** WARNING template declaration not supported ``";
+// Token const &tk = _M_token_stream->token ((int) node->start_token);
+// Token const &end_tk = _M_token_stream->token ((int) node->declaration->start_token);
+
+// std::cerr << std::string (&tk.text[tk.position], (end_tk.position) - tk.position) << "''"
+// << std::endl << std::endl;
+
+ changeTemplateParameters(savedTemplateParameters);
+ return;
+ }
+ assert(tk == Token_typename || tk == Token_class);
+
+ name_cc.run(type_parameter->name);
+ p->setName(name_cc.name());
+
+ _M_current_template_parameters.append(p);
+ it = it->next;
+ }
+ while (it != end);
+
+ visit(node->declaration);
+
+ changeTemplateParameters(savedTemplateParameters);
+}
+
+void Binder::visitTypedef(TypedefAST *node)
+{
+ const ListNode<InitDeclaratorAST*> *it = node->init_declarators;
+ if (it == 0)
+ return;
+
+ it = it->toFront();
+ const ListNode<InitDeclaratorAST*> *end = it;
+
+ do
+ {
+ InitDeclaratorAST *init_declarator = it->element;
+ it = it->next;
+
+ Q_ASSERT(init_declarator->declarator != 0);
+
+ // the name
+ decl_cc.run (init_declarator->declarator);
+ QString alias_name = decl_cc.id ();
+
+ if (alias_name.isEmpty ())
+ {
+ std::cerr << "** WARNING anonymous typedef not supported! ``";
+ Token const &tk = _M_token_stream->token ((int) node->start_token);
+ Token const &end_tk = _M_token_stream->token ((int) node->end_token);
+
+ std::cerr << std::string (&tk.text[tk.position], end_tk.position - tk.position) << "''"
+ << std::endl << std::endl;
+ continue;
+ }
+
+ // build the type
+ TypeInfo typeInfo = CompilerUtils::typeDescription (node->type_specifier,
+ init_declarator->declarator,
+ this);
+ DeclaratorAST *decl = init_declarator->declarator;
+ while (decl && decl->sub_declarator)
+ decl = decl->sub_declarator;
+
+ if (decl != init_declarator->declarator
+ && init_declarator->declarator->parameter_declaration_clause != 0)
+ {
+ typeInfo.setFunctionPointer (true);
+ decl_cc.run (init_declarator->declarator);
+ foreach (DeclaratorCompiler::Parameter p, decl_cc.parameters())
+ typeInfo.addArgument(p.type);
+ }
+
+ ScopeModelItem scope = currentScope();
+ DeclaratorAST *declarator = init_declarator->declarator;
+ CodeModelFinder finder(model(), this);
+ ScopeModelItem typedefScope = finder.resolveScope(declarator->id, scope);
+
+ TypeAliasModelItem typeAlias = model ()->create<TypeAliasModelItem> ();
+ updateItemPosition (typeAlias->toItem (), node);
+ typeAlias->setName (alias_name);
+ typeAlias->setType (qualifyType (typeInfo, currentScope ()->qualifiedName ()));
+ typeAlias->setScope (typedefScope->qualifiedName());
+ _M_qualified_types[typeAlias->qualifiedName().join(".")] = QString();
+ currentScope ()->addTypeAlias (typeAlias);
+ }
+ while (it != end);
+}
+
+void Binder::visitNamespace(NamespaceAST *node)
+{
+ bool anonymous = (node->namespace_name == 0);
+
+ ScopeModelItem scope = currentScope();
+
+ NamespaceModelItem old;
+ if (! anonymous)
+ {
+ QString name = decode_symbol(node->namespace_name)->as_string();
+
+ QStringList qualified_name = scope->qualifiedName();
+ qualified_name += name;
+ NamespaceModelItem ns =
+ model_safe_cast<NamespaceModelItem>(_M_model->findItem(qualified_name,
+ _M_current_file->toItem()));
+ if (!ns)
+ {
+ ns = _M_model->create<NamespaceModelItem>();
+ updateItemPosition (ns->toItem(), node);
+ ns->setName(name);
+ ns->setScope(scope->qualifiedName());
+ }
+ old = changeCurrentNamespace(ns);
+
+ _M_context.append(name);
+ }
+
+ DefaultVisitor::visitNamespace(node);
+
+ if (! anonymous)
+ {
+ Q_ASSERT(scope->kind() == _CodeModelItem::Kind_Namespace
+ || scope->kind() == _CodeModelItem::Kind_File);
+
+ _M_context.removeLast();
+
+ if (NamespaceModelItem ns = model_static_cast<NamespaceModelItem>(scope))
+ {
+ ns->addNamespace(_M_current_namespace);
+ }
+
+ changeCurrentNamespace(old);
+ }
+}
+
+void Binder::visitClassSpecifier(ClassSpecifierAST *node)
+{
+ ClassCompiler class_cc(this);
+ class_cc.run(node);
+
+ if (class_cc.name().isEmpty())
+ {
+ // anonymous not supported
+ return;
+ }
+
+ Q_ASSERT(node->name != 0 && node->name->unqualified_name != 0);
+
+ ScopeModelItem scope = currentScope();
+
+ ClassModelItem old = changeCurrentClass(_M_model->create<ClassModelItem>());
+ updateItemPosition (_M_current_class->toItem(), node);
+ _M_current_class->setName(class_cc.name());
+ _M_current_class->setBaseClasses(class_cc.baseClasses());
+ _M_current_class->setClassType(decode_class_type(node->class_key));
+ _M_current_class->setTemplateParameters(_M_current_template_parameters);
+
+ if (! _M_current_template_parameters.isEmpty())
+ {
+ QString name = _M_current_class->name();
+ name += "<";
+ for (int i = 0; i<_M_current_template_parameters.size(); ++i)
+ {
+ if (i != 0)
+ name += ",";
+
+ name += _M_current_template_parameters.at(i)->name();
+ }
+
+ name += ">";
+ _M_current_class->setName(name);
+ }
+
+ CodeModel::AccessPolicy oldAccessPolicy = changeCurrentAccess(decode_access_policy(node->class_key));
+ CodeModel::FunctionType oldFunctionType = changeCurrentFunctionType(CodeModel::Normal);
+
+ _M_current_class->setScope(scope->qualifiedName());
+ _M_qualified_types[_M_current_class->qualifiedName().join(".")] = QString();
+ scope->addClass(_M_current_class);
+
+ name_cc.run(node->name->unqualified_name);
+ _M_context.append(name_cc.name());
+ visitNodes(this, node->member_specs);
+ _M_context.removeLast();
+
+ changeCurrentClass(old);
+ changeCurrentAccess(oldAccessPolicy);
+ changeCurrentFunctionType(oldFunctionType);
+}
+
+void Binder::visitLinkageSpecification(LinkageSpecificationAST *node)
+{
+ DefaultVisitor::visitLinkageSpecification(node);
+}
+
+void Binder::visitUsing(UsingAST *node)
+{
+ DefaultVisitor::visitUsing(node);
+}
+
+void Binder::visitEnumSpecifier(EnumSpecifierAST *node)
+{
+ CodeModelFinder finder(model(), this);
+ ScopeModelItem scope = currentScope();
+ ScopeModelItem enumScope = finder.resolveScope(node->name, scope);
+
+ name_cc.run(node->name);
+ QString name = name_cc.name();
+
+ if (name.isEmpty())
+ {
+ // anonymous enum
+ QString key = _M_context.join("::");
+ int current = ++_M_anonymous_enums[key];
+ name += QLatin1String("enum_");
+ name += QString::number(current);
+ }
+
+ _M_current_enum = model()->create<EnumModelItem>();
+ _M_current_enum->setAccessPolicy(_M_current_access);
+ updateItemPosition (_M_current_enum->toItem(), node);
+ _M_current_enum->setName(name);
+ _M_current_enum->setScope(enumScope->qualifiedName());
+
+ _M_qualified_types[_M_current_enum->qualifiedName().join(".")] = QString();
+
+ enumScope->addEnum(_M_current_enum);
+
+ DefaultVisitor::visitEnumSpecifier(node);
+
+ _M_current_enum = 0;
+}
+
+void Binder::visitEnumerator(EnumeratorAST *node)
+{
+ Q_ASSERT(_M_current_enum != 0);
+ EnumeratorModelItem e = model()->create<EnumeratorModelItem>();
+ updateItemPosition (e->toItem(), node);
+ e->setName(decode_symbol(node->id)->as_string());
+
+ if (ExpressionAST *expr = node->expression)
+ {
+ const Token &start_token = _M_token_stream->token((int) expr->start_token);
+ const Token &end_token = _M_token_stream->token((int) expr->end_token);
+
+ e->setValue(QString::fromUtf8(&start_token.text[start_token.position],
+ (int) (end_token.position - start_token.position)).trimmed());
+ }
+
+ _M_current_enum->addEnumerator(e);
+}
+
+void Binder::visitUsingDirective(UsingDirectiveAST *node)
+{
+ DefaultVisitor::visitUsingDirective(node);
+}
+
+void Binder::visitQProperty(QPropertyAST *node)
+{
+ const Token &start = _M_token_stream->token((int) node->start_token);
+ const Token &end = _M_token_stream->token((int) node->end_token);
+ QString property = QString::fromLatin1(start.text + start.position,
+ end.position - start.position);
+ _M_current_class->addPropertyDeclaration(property);
+}
+
+void Binder::applyStorageSpecifiers(const ListNode<std::size_t> *it, MemberModelItem item)
+{
+ if (it == 0)
+ return;
+
+ it = it->toFront();
+ const ListNode<std::size_t> *end = it;
+
+ do
+ {
+ switch (decode_token(it->element))
+ {
+ default:
+ break;
+
+ case Token_friend:
+ item->setFriend(true);
+ break;
+ case Token_auto:
+ item->setAuto(true);
+ break;
+ case Token_register:
+ item->setRegister(true);
+ break;
+ case Token_static:
+ item->setStatic(true);
+ break;
+ case Token_extern:
+ item->setExtern(true);
+ break;
+ case Token_mutable:
+ item->setMutable(true);
+ break;
+ }
+ it = it->next;
+ }
+ while (it != end);
+}
+
+void Binder::applyFunctionSpecifiers(const ListNode<std::size_t> *it, FunctionModelItem item)
+{
+ if (it == 0)
+ return;
+
+ it = it->toFront();
+ const ListNode<std::size_t> *end = it;
+
+ do
+ {
+ switch (decode_token(it->element))
+ {
+ default:
+ break;
+
+ case Token_inline:
+ item->setInline(true);
+ break;
+
+ case Token_virtual:
+ item->setVirtual(true);
+ break;
+
+ case Token_explicit:
+ item->setExplicit(true);
+ break;
+ }
+ it = it->next;
+ }
+ while (it != end);
+}
+
+TypeInfo Binder::qualifyType(const TypeInfo &type, const QStringList &context) const
+{
+ // ### Potentially improve to use string list in the name table to
+ if (context.size() == 0)
+ {
+ // ### We can assume that this means global namespace for now...
+ return type;
+ }
+ else if (_M_qualified_types.contains(type.qualifiedName().join(".")))
+ {
+ return type;
+ }
+ else
+ {
+ QStringList expanded = context;
+ expanded << type.qualifiedName();
+ if (_M_qualified_types.contains(expanded.join(".")))
+ {
+ TypeInfo modified_type = type;
+ modified_type.setQualifiedName(expanded);
+ return modified_type;
+ }
+ else
+ {
+ CodeModelItem scope = model ()->findItem (context, _M_current_file->toItem ());
+
+ if (ClassModelItem klass = model_dynamic_cast<ClassModelItem> (scope))
+ {
+ foreach (QString base, klass->baseClasses ())
+ {
+ QStringList ctx = context;
+ ctx.removeLast();
+ ctx.append (base);
+
+ TypeInfo qualified = qualifyType (type, ctx);
+ if (qualified != type)
+ return qualified;
+ }
+ }
+
+ QStringList copy = context;
+ copy.removeLast();
+ return qualifyType(type, copy);
+ }
+ }
+}
+
+void Binder::updateItemPosition(CodeModelItem item, AST *node)
+{
+ QString filename;
+ int line, column;
+
+ assert (node != 0);
+ _M_location.positionAt (_M_token_stream->position(node->start_token), &line, &column, &filename);
+ item->setFileName (filename);
+}
+
+// kate: space-indent on; indent-width 2; replace-tabs on;
135 src/binder.h
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.
+**
+** This file is part of Qt Jambi.
+**
+** ** This file may be used under the terms of the GNU General Public
+** License version 2.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.trolltech.com/products/qt/opensource.html
+**
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://www.trolltech.com/products/qt/licensing.html or contact the
+** sales department at sales@trolltech.com.
+
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+/* This file is part of KDevelop
+ Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org>
+ Copyright (C) 2005 Trolltech AS
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef BINDER_H
+#define BINDER_H
+
+#include "default_visitor.h"
+#include "codemodel.h"
+#include "type_compiler.h"
+#include "name_compiler.h"
+#include "declarator_compiler.h"
+
+class TokenStream;
+class LocationManager;
+class Control;
+struct NameSymbol;
+
+class Binder: protected DefaultVisitor
+{
+public:
+ Binder(CodeModel *__model, LocationManager &__location, Control *__control = 0);
+ virtual ~Binder();
+
+ inline TokenStream *tokenStream() const { return _M_token_stream; }
+ inline CodeModel *model() const { return _M_model; }
+ ScopeModelItem currentScope();
+
+ FileModelItem run(AST *node);
+
+// utils
+ TypeInfo qualifyType(const TypeInfo &type, const QStringList &context) const;
+
+protected:
+ virtual void visitAccessSpecifier(AccessSpecifierAST *);
+ virtual void visitClassSpecifier(ClassSpecifierAST *);
+ virtual void visitEnumSpecifier(EnumSpecifierAST *);
+ virtual void visitEnumerator(EnumeratorAST *);
+ virtual void visitFunctionDefinition(FunctionDefinitionAST *);
+ virtual void visitLinkageSpecification(LinkageSpecificationAST *);
+ virtual void visitNamespace(NamespaceAST *);
+ virtual void visitSimpleDeclaration(SimpleDeclarationAST *);
+ virtual void visitTemplateDeclaration(TemplateDeclarationAST *);
+ virtual void visitTypedef(TypedefAST *);
+ virtual void visitUsing(UsingAST *);
+ virtual void visitUsingDirective(UsingDirectiveAST *);
+ virtual void visitQProperty(QPropertyAST *);
+
+private:
+
+ int decode_token(std::size_t index) const;
+ const NameSymbol *decode_symbol(std::size_t index) const;
+ CodeModel::AccessPolicy decode_access_policy(std::size_t index) const;
+ CodeModel::ClassType decode_class_type(std::size_t index) const;
+
+ CodeModel::FunctionType changeCurrentFunctionType(CodeModel::FunctionType functionType);
+ CodeModel::AccessPolicy changeCurrentAccess(CodeModel::AccessPolicy accessPolicy);
+ NamespaceModelItem changeCurrentNamespace(NamespaceModelItem item);
+ ClassModelItem changeCurrentClass(ClassModelItem item);
+ FunctionDefinitionModelItem changeCurrentFunction(FunctionDefinitionModelItem item);
+ TemplateParameterList changeTemplateParameters(TemplateParameterList templateParameters);
+
+ void declare_symbol(SimpleDeclarationAST *node, InitDeclaratorAST *init_declarator);
+
+ void applyStorageSpecifiers(const ListNode<std::size_t> *storage_specifiers, MemberModelItem item);
+ void applyFunctionSpecifiers(const ListNode<std::size_t> *it, FunctionModelItem item);
+
+ void updateItemPosition(CodeModelItem item, AST *node);
+
+private:
+ CodeModel *_M_model;
+ LocationManager &_M_location;
+ TokenStream *_M_token_stream;
+ Control *_M_control;
+
+ CodeModel::FunctionType _M_current_function_type;
+ CodeModel::AccessPolicy _M_current_access;
+ FileModelItem _M_current_file;
+ NamespaceModelItem _M_current_namespace;
+ ClassModelItem _M_current_class;
+ FunctionDefinitionModelItem _M_current_function;
+ EnumModelItem _M_current_enum;
+ QStringList _M_context;
+ TemplateParameterList _M_current_template_parameters; // ### check me
+ QHash<QString, QString> _M_qualified_types;
+ QHash<QString, int> _M_anonymous_enums;
+
+protected:
+ TypeCompiler type_cc;
+ NameCompiler name_cc;
+ DeclaratorCompiler decl_cc;
+};
+
+#endif // BINDER_H
+
+// kate: space-indent on; indent-width 2; replace-tabs on;
83 src/class_compiler.cpp
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.
+**
+** This file is part of Qt Jambi.
+**
+** ** This file may be used under the terms of the GNU General Public
+** License version 2.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.trolltech.com/products/qt/opensource.html
+**
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://www.trolltech.com/products/qt/licensing.html or contact the
+** sales department at sales@trolltech.com.
+
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+/* This file is part of KDevelop
+ Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "class_compiler.h"
+#include "lexer.h"
+#include "binder.h"
+
+ClassCompiler::ClassCompiler(Binder *binder)
+ : _M_binder (binder),
+ _M_token_stream(binder->tokenStream ()),
+ name_cc(_M_binder),
+ type_cc(_M_binder)
+{
+}
+
+ClassCompiler::~ClassCompiler()
+{
+}
+
+void ClassCompiler::run(ClassSpecifierAST *node)
+{
+ name_cc.run(node->name);
+ _M_name = name_cc.name();
+ _M_base_classes.clear();
+
+ visit(node);
+}
+
+void ClassCompiler::visitClassSpecifier(ClassSpecifierAST *node)
+{
+ visit(node->base_clause);
+}
+
+void ClassCompiler::visitBaseSpecifier(BaseSpecifierAST *node)
+{
+ name_cc.run(node->name);
+ QString name = name_cc.name();
+
+ if (! name.isEmpty())
+ _M_base_classes.append(name);
+}
+
+
+// kate: space-indent on; indent-width 2; replace-tabs on;
82 src/class_compiler.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.
+**
+** This file is part of Qt Jambi.
+**
+** ** This file may be used under the terms of the GNU General Public
+** License version 2.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.trolltech.com/products/qt/opensource.html
+**
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://www.trolltech.com/products/qt/licensing.html or contact the
+** sales department at sales@trolltech.com.
+
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+/* This file is part of KDevelop
+ Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef CLASS_COMPILER_H
+#define CLASS_COMPILER_H
+
+#include <QtCore/qglobal.h>
+#include <QtCore/QStringList>
+
+#include "default_visitor.h"
+#include "name_compiler.h"
+#include "type_compiler.h"
+
+class TokenStream;
+class Binder;
+
+class ClassCompiler: protected DefaultVisitor
+{
+public:
+ ClassCompiler(Binder *binder);
+ virtual ~ClassCompiler();
+
+ inline QString name() const { return _M_name; }
+ inline QStringList baseClasses() const { return _M_base_classes; }
+
+ void run(ClassSpecifierAST *node);
+
+protected:
+ virtual void visitClassSpecifier(ClassSpecifierAST *node);
+ virtual void visitBaseSpecifier(BaseSpecifierAST *node);
+
+private:
+ Binder *_M_binder;
+ TokenStream *_M_token_stream;
+ QString _M_name;
+ QStringList _M_base_classes;
+ NameCompiler name_cc;
+ TypeCompiler type_cc;
+};
+
+#endif // CLASS_COMPILER_H
+
+// kate: space-indent on; indent-width 2; replace-tabs on;
945 src/codemodel.cpp
@@ -0,0 +1,945 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.
+**
+** This file is part of Qt Jambi.
+**
+** ** This file may be used under the terms of the GNU General Public
+** License version 2.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.trolltech.com/products/qt/opensource.html
+**
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://www.trolltech.com/products/qt/licensing.html or contact the
+** sales department at sales@trolltech.com.
+
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+
+/* This file is part of KDevelop
+ Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org>
+ Copyright (C) 2005 Trolltech AS
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "codemodel.h"
+
+// ---------------------------------------------------------------------------
+CodeModel::CodeModel()
+ : _M_creation_id(0)
+{
+ _M_globalNamespace = create<NamespaceModelItem>();
+}
+
+CodeModel::~CodeModel()
+{
+}
+
+void CodeModel::wipeout()
+{
+ _M_globalNamespace = create<NamespaceModelItem>();
+ _M_files.clear();
+}
+
+FileList CodeModel::files() const
+{
+ return _M_files.values();
+}
+
+NamespaceModelItem CodeModel::globalNamespace() const
+{
+ return _M_globalNamespace;
+}
+
+void CodeModel::addFile(FileModelItem item)
+{
+ _M_creation_id = 0; // reset the creation id
+ _M_files.insert(item->name(), item);
+}
+
+void CodeModel::removeFile(FileModelItem item)
+{
+ QHash<QString, FileModelItem>::Iterator it = _M_files.find(item->name());
+
+ if (it != _M_files.end() && it.value() == item)
+ _M_files.erase(it);
+}
+
+FileModelItem CodeModel::findFile(const QString &name) const
+{
+ return _M_files.value(name);
+}
+
+QHash<QString, FileModelItem> CodeModel::fileMap() const
+{
+ return _M_files;
+}
+
+CodeModelItem CodeModel::findItem(const QStringList &qualifiedName, CodeModelItem scope) const
+{
+ for (int i=0; i<qualifiedName.size(); ++i) {
+ // ### Extend to look for members etc too.
+ const QString &name = qualifiedName.at(i);
+
+ if (NamespaceModelItem ns = model_dynamic_cast<NamespaceModelItem>(scope))
+ {
+ if (NamespaceModelItem tmp_ns = ns->findNamespace(name)) {
+ scope = tmp_ns;
+ continue;
+ }
+ }
+
+ if (ScopeModelItem ss = model_dynamic_cast<ScopeModelItem>(scope))
+ {
+ if (ClassModelItem cs = ss->findClass(name))
+ {
+ scope = cs;
+ }
+ else if (EnumModelItem es = ss->findEnum(name))
+ {
+ if (i == qualifiedName.size () - 1)
+ return es->toItem();
+ }
+ else if (TypeAliasModelItem tp = ss->findTypeAlias(name))
+ {
+ if (i == qualifiedName.size () - 1)
+ return tp->toItem ();
+ }
+ }
+ }
+
+ return scope;
+}
+
+
+// ---------------------------------------------------------------------------
+TypeInfo TypeInfo::combine (const TypeInfo &__lhs, const TypeInfo &__rhs)
+{
+ TypeInfo __result = __lhs;
+
+ __result.setConstant (__result.isConstant () || __rhs.isConstant ());
+ __result.setVolatile (__result.isVolatile () || __rhs.isVolatile ());
+ __result.setReference (__result.isReference () || __rhs.isReference ());
+ __result.setIndirections (__result.indirections () + __rhs.indirections ());
+ __result.setArrayElements (__result.arrayElements () + __rhs.arrayElements ());
+
+ return __result;
+}
+
+TypeInfo TypeInfo::resolveType (TypeInfo const &__type, CodeModelItem __scope)
+{
+ CodeModel *__model = __scope->model ();
+ Q_ASSERT (__model != 0);
+
+ CodeModelItem __item = __model->findItem (__type.qualifiedName (), __scope);
+
+ // Copy the type and replace with the proper qualified name. This
+ // only makes sence to do if we're actually getting a resolved
+ // type with a namespace. We only get this if the returned type
+ // has more than 2 entries in the qualified name... This test
+ // could be improved by returning if the type was found or not.
+ TypeInfo otherType(__type);
+ if (__item->qualifiedName().size() > 1) {
+ otherType.setQualifiedName(__item->qualifiedName());
+ }
+
+ if (TypeAliasModelItem __alias = model_dynamic_cast<TypeAliasModelItem> (__item))
+ return resolveType (TypeInfo::combine (__alias->type (), otherType), __scope);
+
+ return otherType;
+}
+
+QString TypeInfo::toString() const
+{
+ QString tmp;
+
+ tmp += m_qualifiedName.join("::");
+ if (isConstant())
+ tmp += QLatin1String(" const");
+
+ if (isVolatile())
+ tmp += QLatin1String(" volatile");
+
+ if (indirections())
+ tmp += QString(indirections(), QLatin1Char('*'));
+
+ if (isReference())
+ tmp += QLatin1Char('&');
+
+ if (isFunctionPointer())
+ {
+ tmp += QLatin1String(" (*)(");
+ for (int i=0; i<m_arguments.count(); ++i)
+ {
+ if (i != 0)
+ tmp += QLatin1String(", ");
+
+ tmp += m_arguments.at(i).toString();
+ }
+ tmp += QLatin1String(")");
+ }
+
+ foreach (QString elt, arrayElements ())
+ {
+ tmp += QLatin1String ("[");
+ tmp += elt;
+ tmp += QLatin1String ("]");
+ }
+
+ return tmp;
+}
+
+bool TypeInfo::operator==(const TypeInfo &other)
+{
+ if (arrayElements().count() != other.arguments().count())
+ return false;
+
+#if defined (RXX_CHECK_ARRAY_ELEMENTS) // ### it'll break
+ for (int i=0; i<arrayElements().count(); ++i)
+ {