From bfe36575b74ce96dba1b4802a97be7c9a37232f3 Mon Sep 17 00:00:00 2001 From: Roberto Raggi <roberto.raggi@nokia.com> Date: Tue, 24 Feb 2009 11:04:52 +0100 Subject: [PATCH] Introduced a parallel indexer. It is ifdef-out atm. --- src/libs/cplusplus/CppDocument.cpp | 23 +++++- src/libs/cplusplus/CppDocument.h | 8 ++ src/plugins/cpptools/cppmodelmanager.cpp | 94 ++++++++++++++++++------ 3 files changed, 102 insertions(+), 23 deletions(-) diff --git a/src/libs/cplusplus/CppDocument.cpp b/src/libs/cplusplus/CppDocument.cpp index 8c2d6265909..a0ae6760d61 100644 --- a/src/libs/cplusplus/CppDocument.cpp +++ b/src/libs/cplusplus/CppDocument.cpp @@ -230,7 +230,8 @@ Document::Ptr Document::create(const QString &fileName) void Document::setSource(const QByteArray &source) { - _translationUnit->setSource(source.constBegin(), source.size()); + _source = source; + _translationUnit->setSource(_source.constBegin(), _source.size()); } void Document::startSkippingBlocks(unsigned start) @@ -250,6 +251,21 @@ void Document::stopSkippingBlocks(unsigned stop) _skippedBlocks.back() = Block(start, stop); } +bool Document::isTokenized() const +{ + return _translationUnit->isTokenized(); +} + +void Document::tokenize() +{ + _translationUnit->tokenize(); +} + +bool Document::isParsed() const +{ + return _translationUnit->isParsed(); +} + bool Document::parse(ParseMode mode) { TranslationUnit::ParseMode m = TranslationUnit::ParseTranlationUnit; @@ -295,6 +311,11 @@ void Document::check() } } +void Document::releaseSource() +{ + _source.clear(); +} + void Document::releaseTranslationUnit() { _translationUnit->release(); diff --git a/src/libs/cplusplus/CppDocument.h b/src/libs/cplusplus/CppDocument.h index 73bae23679c..90946a5295d 100644 --- a/src/libs/cplusplus/CppDocument.h +++ b/src/libs/cplusplus/CppDocument.h @@ -96,8 +96,15 @@ public: ParseStatement }; + bool isTokenized() const; + void tokenize(); + + bool isParsed() const; bool parse(ParseMode mode = ParseTranlationUnit); + void check(); + + void releaseSource(); void releaseTranslationUnit(); static Ptr create(const QString &fileName); @@ -233,6 +240,7 @@ private: QList<Macro> _definedMacros; QList<Block> _skippedBlocks; QList<MacroUse> _macroUses; + QByteArray _source; }; class CPLUSPLUS_EXPORT Snapshot: public QMap<QString, Document::Ptr> diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index c7cda11081e..586ea67c0e2 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -73,6 +73,7 @@ #include <QtCore/QMutexLocker> #include <QtCore/QTime> #include <QtCore/QTimer> +#include <QtConcurrentMap> #include <iostream> #include <sstream> @@ -171,8 +172,8 @@ public: void setProjectFiles(const QStringList &files); void setTodo(const QStringList &files); - void run(QString &fileName); - void operator()(QString &fileName); + void run(const QString &fileName); + void run_helper(const QString &fileName, QList<Document::Ptr> *documents); void resetEnvironment(); @@ -211,8 +212,9 @@ private: QStringList m_projectFiles; QStringList m_frameworkPaths; QSet<QString> m_included; - CPlusPlus::Document::Ptr m_currentDoc; + Document::Ptr m_currentDoc; QSet<QString> m_todo; + QList<Document::Ptr> *m_documents; }; } // namespace Internal @@ -221,7 +223,8 @@ private: CppPreprocessor::CppPreprocessor(QPointer<CppModelManager> modelManager) : snapshot(modelManager->snapshot()), m_modelManager(modelManager), - m_proc(this, env) + m_proc(this, env), + m_documents(0) { } void CppPreprocessor::setWorkingCopy(const QMap<QString, QByteArray> &workingCopy) @@ -239,15 +242,70 @@ void CppPreprocessor::setProjectFiles(const QStringList &files) void CppPreprocessor::setTodo(const QStringList &files) { m_todo = QSet<QString>::fromList(files); } -void CppPreprocessor::run(QString &fileName) -{ sourceNeeded(fileName, IncludeGlobal, /*line = */ 0); } + +namespace { + +class Process +{ + QPointer<CppModelManager> _modelManager; + +public: + Process(QPointer<CppModelManager> modelManager) + : _modelManager(modelManager) + { } + + void operator()(Document::Ptr doc) + { + doc->parse(); + doc->check(); + doc->releaseTranslationUnit(); + + if (_modelManager) + _modelManager->emitDocumentUpdated(doc); // ### TODO: compress + } +}; + +} // end of anonymous namespace + +// #define QTCREATOR_WITH_PARALLEL_INDEXER + +void CppPreprocessor::run(const QString &fileName) +{ + QList<Document::Ptr> documents; + run_helper(fileName, &documents); + +#ifdef QTCREATOR_WITH_PARALLEL_INDEXER + QFuture<void> future = QtConcurrent::map(documents, Process(m_modelManager)); + future.waitForFinished(); + +#else + foreach (Document::Ptr doc, documents) { + doc->parse(); + doc->check(); + + doc->releaseTranslationUnit(); + + if (m_modelManager) + m_modelManager->emitDocumentUpdated(doc); // ### TODO: compress + } +#endif +} + +void CppPreprocessor::run_helper(const QString &fileName, + QList<Document::Ptr> *documents) +{ + QList<Document::Ptr> *previousDocuments = m_documents; + m_documents = documents; + + QString absoluteFilePath = fileName; + sourceNeeded(absoluteFilePath, IncludeGlobal, /*line = */ 0); + + m_documents = previousDocuments; +} void CppPreprocessor::resetEnvironment() { env.reset(); } -void CppPreprocessor::operator()(QString &fileName) -{ run(fileName); } - bool CppPreprocessor::includeFile(const QString &absoluteFilePath, QByteArray *result) { if (absoluteFilePath.isEmpty() || m_included.contains(absoluteFilePath)) { @@ -475,23 +533,15 @@ void CppPreprocessor::sourceNeeded(QString &fileName, IncludeType type, m_proc(fileName.toUtf8(), contents, &preprocessedCode); doc->setSource(preprocessedCode); + doc->tokenize(); + doc->releaseSource(); - doc->parse(); - doc->check(); - -#if defined(QTCREATOR_WITH_DUMP_AST) && defined(Q_CC_GNU) - DumpAST dump(m_currentDoc->control()); - dump(m_currentDoc->translationUnit()->ast()); -#endif - - doc->releaseTranslationUnit(); + snapshot.insert(doc->fileName(), doc); - snapshot[fileName] = doc; - - if (m_modelManager) - m_modelManager->emitDocumentUpdated(m_currentDoc); // ### TODO: compress + m_documents->append(doc); (void) switchDocument(previousDoc); + m_todo.remove(fileName); } -- GitLab