diff options
author | Erik Verbruggen <erik.verbruggen@digia.com> | 2014-01-10 12:48:03 +0100 |
---|---|---|
committer | Nikolai Kosjar <nikolai.kosjar@digia.com> | 2014-01-10 15:33:50 +0100 |
commit | a4b6e35ac4c9d32d9a1e889f9379a25ab0d6c637 (patch) | |
tree | de9d23889408ddf992b5d82b8c3b3a42e812420b | |
parent | 2251958375321463995990fc59a88cbc2235c532 (diff) | |
download | qt-creator-a4b6e35ac4c9d32d9a1e889f9379a25ab0d6c637.tar.gz |
Clang: clean up unit handling.
- Use a QSharedPointer instead of an explicitly shared pointer.
- Remove the LiveUnitManager.
Change-Id: I05bf32c1f77c17f42ee1da39f1353cff580fa6eb
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@digia.com>
19 files changed, 144 insertions, 417 deletions
diff --git a/src/plugins/clangcodemodel/clangcodemodel.pro b/src/plugins/clangcodemodel/clangcodemodel.pro index 9267be19c1..28b111b42e 100644 --- a/src/plugins/clangcodemodel/clangcodemodel.pro +++ b/src/plugins/clangcodemodel/clangcodemodel.pro @@ -35,7 +35,6 @@ SOURCES += \ $$PWD/unit.cpp \ $$PWD/utils.cpp \ $$PWD/utils_p.cpp \ - $$PWD/liveunitsmanager.cpp \ $$PWD/semanticmarker.cpp \ $$PWD/diagnostic.cpp \ $$PWD/unsavedfiledata.cpp \ @@ -58,7 +57,6 @@ HEADERS += \ $$PWD/unit.h \ $$PWD/utils.h \ $$PWD/utils_p.h \ - $$PWD/liveunitsmanager.h \ $$PWD/semanticmarker.h \ $$PWD/diagnostic.h \ $$PWD/unsavedfiledata.h \ diff --git a/src/plugins/clangcodemodel/clangcodemodel.qbs b/src/plugins/clangcodemodel/clangcodemodel.qbs index 1044984bdc..170b720c4b 100644 --- a/src/plugins/clangcodemodel/clangcodemodel.qbs +++ b/src/plugins/clangcodemodel/clangcodemodel.qbs @@ -163,8 +163,6 @@ QtcPlugin { "diagnostic.h", "fastindexer.cpp", "fastindexer.h", - "liveunitsmanager.cpp", - "liveunitsmanager.h", "pchinfo.cpp", "pchinfo.h", "pchmanager.cpp", diff --git a/src/plugins/clangcodemodel/clangcodemodelplugin.cpp b/src/plugins/clangcodemodel/clangcodemodelplugin.cpp index 2e04c5dbaa..e652f5ffa6 100644 --- a/src/plugins/clangcodemodel/clangcodemodelplugin.cpp +++ b/src/plugins/clangcodemodel/clangcodemodelplugin.cpp @@ -58,11 +58,6 @@ bool ClangCodeModelPlugin::initialize(const QStringList &arguments, QString *err ClangCodeModel::Internal::initializeClang(); - connect(Core::EditorManager::instance(), SIGNAL(editorAboutToClose(Core::IEditor*)), - &m_liveUnitsManager, SLOT(editorAboutToClose(Core::IEditor*))); - connect(Core::EditorManager::instance(), SIGNAL(editorOpened(Core::IEditor*)), - &m_liveUnitsManager, SLOT(editorOpened(Core::IEditor*))); - PCHManager *pchManager = new PCHManager(this); FastIndexer *fastIndexer = 0; diff --git a/src/plugins/clangcodemodel/clangcodemodelplugin.h b/src/plugins/clangcodemodel/clangcodemodelplugin.h index 5243ddb702..8faaef44c5 100644 --- a/src/plugins/clangcodemodel/clangcodemodelplugin.h +++ b/src/plugins/clangcodemodel/clangcodemodelplugin.h @@ -31,7 +31,6 @@ #define CLANGPLUGIN_H #include "clangmodelmanagersupport.h" -#include "liveunitsmanager.h" #ifdef CLANG_INDEXING # include "clangindexer.h" @@ -53,7 +52,6 @@ public: void extensionsInitialized(); private: - LiveUnitsManager m_liveUnitsManager; QScopedPointer<ModelManagerSupport> m_modelManagerSupport; #ifdef CLANG_INDEXING QScopedPointer<ClangIndexer> m_indexer; diff --git a/src/plugins/clangcodemodel/clangcompleter.cpp b/src/plugins/clangcodemodel/clangcompleter.cpp index 46ef47428c..452385fad5 100644 --- a/src/plugins/clangcodemodel/clangcompleter.cpp +++ b/src/plugins/clangcodemodel/clangcompleter.cpp @@ -50,6 +50,7 @@ class ClangCodeModel::ClangCompleter::PrivateData public: PrivateData() : m_mutex(QMutex::Recursive) + , m_unit(Internal::Unit::create()) , m_isSignalSlotCompletion(false) { } @@ -60,8 +61,8 @@ public: bool parseFromFile(const Internal::UnsavedFiles &unsavedFiles) { - Q_ASSERT(!m_unit.isLoaded()); - if (m_unit.fileName().isEmpty()) + Q_ASSERT(!m_unit->isLoaded()); + if (m_unit->fileName().isEmpty()) return false; unsigned opts = clang_defaultEditingTranslationUnitOptions(); @@ -69,16 +70,16 @@ public: opts |= CXTranslationUnit_CacheCompletionResults; opts |= CXTranslationUnit_IncludeBriefCommentsInCodeCompletion; #endif - m_unit.setManagementOptions(opts); + m_unit->setManagementOptions(opts); - m_unit.setUnsavedFiles(unsavedFiles); - m_unit.parse(); - return m_unit.isLoaded(); + m_unit->setUnsavedFiles(unsavedFiles); + m_unit->parse(); + return m_unit->isLoaded(); } public: QMutex m_mutex; - Internal::Unit m_unit; + Internal::Unit::Ptr m_unit; bool m_isSignalSlotCompletion; }; @@ -119,26 +120,26 @@ ClangCompleter::~ClangCompleter() QString ClangCompleter::fileName() const { - return d->m_unit.fileName(); + return d->m_unit->fileName(); } void ClangCompleter::setFileName(const QString &fileName) { - if (d->m_unit.fileName() != fileName) { - d->m_unit = Internal::Unit(fileName); + if (d->m_unit->fileName() != fileName) { + d->m_unit = Internal::Unit::create(fileName); } } QStringList ClangCompleter::options() const { - return d->m_unit.compilationOptions(); + return d->m_unit->compilationOptions(); } void ClangCompleter::setOptions(const QStringList &options) const { - if (d->m_unit.compilationOptions() != options) { - d->m_unit.setCompilationOptions(options); - d->m_unit.unload(); + if (d->m_unit->compilationOptions() != options) { + d->m_unit->setCompilationOptions(options); + d->m_unit->unload(); } } @@ -154,12 +155,12 @@ void ClangCompleter::setSignalSlotCompletion(bool isSignalSlot) bool ClangCompleter::reparse(const UnsavedFiles &unsavedFiles) { - if (!d->m_unit.isLoaded()) + if (!d->m_unit->isLoaded()) return d->parseFromFile(unsavedFiles); - d->m_unit.setUnsavedFiles(unsavedFiles); - d->m_unit.reparse(); - return d->m_unit.isLoaded(); + d->m_unit->setUnsavedFiles(unsavedFiles); + d->m_unit->reparse(); + return d->m_unit->isLoaded(); } QList<CodeCompletionResult> ClangCompleter::codeCompleteAt(unsigned line, @@ -170,13 +171,13 @@ QList<CodeCompletionResult> ClangCompleter::codeCompleteAt(unsigned line, QTime t;t.start(); #endif // TIME_COMPLETION - if (!d->m_unit.isLoaded()) + if (!d->m_unit->isLoaded()) if (!d->parseFromFile(unsavedFiles)) return QList<CodeCompletionResult>(); ScopedCXCodeCompleteResults results; - d->m_unit.setUnsavedFiles(unsavedFiles); - d->m_unit.codeCompleteAt(line, column, results); + d->m_unit->setUnsavedFiles(unsavedFiles); + d->m_unit->codeCompleteAt(line, column, results); QList<CodeCompletionResult> completions; if (results) { @@ -198,7 +199,7 @@ bool ClangCompleter::objcEnabled() const static const QString objcppOption = QLatin1String("-ObjC++"); static const QString objcOption = QLatin1String("-ObjC"); - QStringList options = d->m_unit.compilationOptions(); + QStringList options = d->m_unit->compilationOptions(); return options.contains(objcOption) || options.contains(objcppOption); } diff --git a/src/plugins/clangcodemodel/clangindexer.cpp b/src/plugins/clangcodemodel/clangindexer.cpp index 31b8152494..34449b2f3c 100644 --- a/src/plugins/clangcodemodel/clangindexer.cpp +++ b/src/plugins/clangcodemodel/clangindexer.cpp @@ -147,11 +147,11 @@ void ClangIndexer::onAboutToSaveSession() m_clangIndexer->finalize(); } -void ClangIndexer::indexNow(const ClangCodeModel::Internal::Unit &unit) +void ClangIndexer::indexNow(Unit::Ptr unit) { typedef CppTools::ProjectPart ProjectPart; - QString file = unit.fileName(); + QString file = unit->fileName(); CppTools::CppModelManagerInterface *mmi = CppTools::CppModelManagerInterface::instance(); const QList<ProjectPart::Ptr> &parts = mmi->projectPart(file); ProjectPart::Ptr part; diff --git a/src/plugins/clangcodemodel/clangindexer.h b/src/plugins/clangcodemodel/clangindexer.h index cd0351de02..ec86f954ce 100644 --- a/src/plugins/clangcodemodel/clangindexer.h +++ b/src/plugins/clangcodemodel/clangindexer.h @@ -72,7 +72,7 @@ public: void match(ClangSymbolSearcher *searcher) const; - void indexNow(const Unit &unit); + void indexNow(Unit::Ptr unit); public slots: void onAboutToLoadSession(const QString &sessionName); diff --git a/src/plugins/clangcodemodel/fastindexer.h b/src/plugins/clangcodemodel/fastindexer.h index b600f47001..1e269ec381 100644 --- a/src/plugins/clangcodemodel/fastindexer.h +++ b/src/plugins/clangcodemodel/fastindexer.h @@ -40,7 +40,7 @@ class FastIndexer public: virtual ~FastIndexer() = 0; - virtual void indexNow(const Unit &unit) = 0; + virtual void indexNow(Unit::Ptr unit) = 0; }; } // Internal namespace diff --git a/src/plugins/clangcodemodel/indexer.cpp b/src/plugins/clangcodemodel/indexer.cpp index 42690b4dc5..2666121bb1 100644 --- a/src/plugins/clangcodemodel/indexer.cpp +++ b/src/plugins/clangcodemodel/indexer.cpp @@ -86,11 +86,12 @@ struct IndexingResult typedef CppTools::ProjectPart ProjectPart; IndexingResult() + : m_unit(Unit::create()) {} IndexingResult(const QVector<Symbol> &symbol, const QSet<QString> &processedFiles, - const Unit &unit, + const Unit::Ptr &unit, const ProjectPart::Ptr &projectPart) : m_symbolsInfo(symbol) , m_processedFiles(processedFiles) @@ -100,7 +101,7 @@ struct IndexingResult QVector<Symbol> m_symbolsInfo; QSet<QString> m_processedFiles; - Unit m_unit; + Unit::Ptr m_unit; ProjectPart::Ptr m_projectPart; }; @@ -259,7 +260,7 @@ protected: foreach (const QString &fn, m_allFiles.keys()) { QVector<ClangCodeModel::Symbol> symbols; unfoldSymbols(symbols, fn); QSet<QString> processedFiles = QSet<QString>::fromList(m_allFiles.keys()); - Unit unit(fn); + Unit::Ptr unit = Unit::create(fn); IndexingResult indexingResult(symbols, processedFiles, unit, projectPart); indexingResults.append(indexingResult); @@ -714,10 +715,14 @@ void IndexerPrivate::runCore(const QHash<QString, FileData> & /*headers*/, typedef QHash<QString, FileData>::const_iterator FileContIt; QHash<ProjectPart::Ptr, QList<IndexerPrivate::FileData> > parts; typedef QHash<ProjectPart::Ptr, QList<IndexerPrivate::FileData> >::Iterator PartIter; - LiveUnitsManager *lum = LiveUnitsManager::instance(); + + QList<Core::IDocument *> docs = Core::EditorManager::documentModel()->openedDocuments(); + QSet<QString> openDocs; + foreach (Core::IDocument *doc, docs) + openDocs.insert(doc->filePath()); for (FileContIt tit = impls.begin(), eit = impls.end(); tit != eit; ++tit) { - if (!tit->m_upToDate && !lum->isTracking(tit.key())) { + if (!tit->m_upToDate && openDocs.contains(tit.key())) { const IndexerPrivate::FileData &fd = tit.value(); parts[fd.m_projectPart].append(fd); } @@ -1278,7 +1283,7 @@ void Indexer::match(ClangSymbolSearcher *searcher) const m_d->match(searcher); } -void Indexer::runQuickIndexing(const Unit &unit, const CppTools::ProjectPart::Ptr &part) +void Indexer::runQuickIndexing(Unit::Ptr unit, const CppTools::ProjectPart::Ptr &part) { m_d->runQuickIndexing(unit, part); } diff --git a/src/plugins/clangcodemodel/indexer.h b/src/plugins/clangcodemodel/indexer.h index 6b5ef61838..e40afaaca9 100644 --- a/src/plugins/clangcodemodel/indexer.h +++ b/src/plugins/clangcodemodel/indexer.h @@ -87,7 +87,7 @@ public: void match(Internal::ClangSymbolSearcher *searcher) const; - void runQuickIndexing(const Internal::Unit &unit, const ProjectPart::Ptr &part); + void runQuickIndexing(Internal::Unit::Ptr unit, const ProjectPart::Ptr &part); signals: void indexingStarted(QFuture<void> future); diff --git a/src/plugins/clangcodemodel/liveunitsmanager.cpp b/src/plugins/clangcodemodel/liveunitsmanager.cpp deleted file mode 100644 index 402af8929e..0000000000 --- a/src/plugins/clangcodemodel/liveunitsmanager.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "liveunitsmanager.h" - -#include <coreplugin/idocument.h> - -using namespace ClangCodeModel; -using namespace Internal; - -LiveUnitsManager *LiveUnitsManager::m_instance = 0; - -LiveUnitsManager::LiveUnitsManager() -{ - Q_ASSERT(!m_instance); - m_instance = this; - - qRegisterMetaType<ClangCodeModel::Internal::Unit>(); -} - -LiveUnitsManager::~LiveUnitsManager() -{ - m_instance = 0; -} - -void LiveUnitsManager::requestTracking(const QString &fileName) -{ - if (!fileName.isEmpty() && !isTracking(fileName)) - m_units.insert(fileName, Unit(fileName)); -} - -void LiveUnitsManager::cancelTrackingRequest(const QString &fileName) -{ - if (!isTracking(fileName)) - return; - - // If no one else is tracking this particular unit, we remove it. - if (m_units[fileName].isUnique()) - m_units.remove(fileName); -} - -void LiveUnitsManager::updateUnit(const QString &fileName, const Unit &unit) -{ - if (!isTracking(fileName)) - return; - - m_units[fileName] = unit; - - emit unitAvailable(unit); -} - -Unit LiveUnitsManager::unit(const QString &fileName) -{ - return m_units.value(fileName); -} - -void LiveUnitsManager::editorOpened(Core::IEditor *editor) -{ - requestTracking(editor->document()->filePath()); -} - -void LiveUnitsManager::editorAboutToClose(Core::IEditor *editor) -{ - cancelTrackingRequest(editor->document()->filePath()); -} diff --git a/src/plugins/clangcodemodel/liveunitsmanager.h b/src/plugins/clangcodemodel/liveunitsmanager.h deleted file mode 100644 index e2b82340be..0000000000 --- a/src/plugins/clangcodemodel/liveunitsmanager.h +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#ifndef LIVEUNITSMANAGER_H -#define LIVEUNITSMANAGER_H - -#include "unit.h" - -#include <coreplugin/editormanager/ieditor.h> - -#include <QtCore/QObject> -#include <QtCore/QString> -#include <QtCore/QHash> - -namespace ClangCodeModel { -namespace Internal { - -class LiveUnitsManager : public QObject -{ - Q_OBJECT - -public: - LiveUnitsManager(); - ~LiveUnitsManager(); - static LiveUnitsManager *instance() - { return m_instance; } - - void requestTracking(const QString &fileName); - bool isTracking(const QString &fileName) const - { return m_units.contains(fileName); } - - void cancelTrackingRequest(const QString &fileName); - - void updateUnit(const QString &fileName, const Unit &unit); - Unit unit(const QString &fileName); - -public slots: - void editorOpened(Core::IEditor *editor); - void editorAboutToClose(Core::IEditor *editor); - -signals: - void unitAvailable(const ClangCodeModel::Internal::Unit &unit); - -private: - static LiveUnitsManager *m_instance; - QHash<QString, Unit> m_units; -}; - -} // Internal -} // ClangCodeModel - -#endif // LIVEUNITSMANAGER_H diff --git a/src/plugins/clangcodemodel/semanticmarker.cpp b/src/plugins/clangcodemodel/semanticmarker.cpp index be8ddb2c3b..fda7700bd3 100644 --- a/src/plugins/clangcodemodel/semanticmarker.cpp +++ b/src/plugins/clangcodemodel/semanticmarker.cpp @@ -61,7 +61,7 @@ void SemanticMarker::setFileName(const QString &fileName) QStringList oldOptions; if (m_unit) oldOptions = m_unit->compilationOptions(); - m_unit.reset(new Unit(fileName)); + m_unit = Unit::create(fileName); if (!oldOptions.isEmpty()) m_unit->setCompilationOptions(oldOptions); @@ -499,7 +499,7 @@ QList<SourceMarker> SemanticMarker::sourceMarkersInRange(unsigned firstLine, return result; } -Unit SemanticMarker::unit() const +Unit::Ptr SemanticMarker::unit() const { - return *m_unit; + return m_unit; } diff --git a/src/plugins/clangcodemodel/semanticmarker.h b/src/plugins/clangcodemodel/semanticmarker.h index 8a3beea61c..43959b4e27 100644 --- a/src/plugins/clangcodemodel/semanticmarker.h +++ b/src/plugins/clangcodemodel/semanticmarker.h @@ -46,10 +46,6 @@ namespace ClangCodeModel { -namespace Internal { -class Unit; -} - class CLANG_EXPORT SemanticMarker { Q_DISABLE_COPY(SemanticMarker) @@ -78,11 +74,11 @@ public: QList<SourceMarker> sourceMarkersInRange(unsigned firstLine, unsigned lastLine); - Internal::Unit unit() const; + Internal::Unit::Ptr unit() const; private: mutable QMutex m_mutex; - QScopedPointer<Internal::Unit> m_unit; + Internal::Unit::Ptr m_unit; }; } // namespace ClangCodeModel diff --git a/src/plugins/clangcodemodel/unit.cpp b/src/plugins/clangcodemodel/unit.cpp index 4eb78d2d2c..f9423465b7 100644 --- a/src/plugins/clangcodemodel/unit.cpp +++ b/src/plugins/clangcodemodel/unit.cpp @@ -30,14 +30,12 @@ #include "unit.h" #include "unsavedfiledata.h" #include "utils_p.h" -#include "raii/scopedclangoptions.h" #include <clang-c/Index.h> #include <QtCore/QByteArray> #include <QtCore/QVector> #include <QtCore/QSharedData> -#include <QtCore/QDateTime> #include <QtAlgorithms> #ifdef DEBUG_UNIT_COUNT @@ -46,251 +44,149 @@ static QBasicAtomicInt unitDataCount = Q_BASIC_ATOMIC_INITIALIZER(0); #endif // DEBUG_UNIT_COUNT -namespace ClangCodeModel { -namespace Internal { - -class UnitData : public QSharedData -{ -public: - UnitData(); - UnitData(const QString &fileName); - ~UnitData(); - - void swap(UnitData *unitData); - - void unload(); - bool isLoaded() const; - - void updateTimeStamp(); - - CXIndex m_index; - CXTranslationUnit m_tu; - QByteArray m_fileName; - QStringList m_compOptions; - SharedClangOptions m_sharedCompOptions; - unsigned m_managementOptions; - UnsavedFiles m_unsaved; - QDateTime m_timeStamp; -}; - -} // Internal -} // Clang - using namespace ClangCodeModel; using namespace ClangCodeModel::Internal; -UnitData::UnitData() +static const int DisplayDiagnostics = qgetenv("QTC_CLANG_VERBOSE").isEmpty() ? 0 : 1; + +Unit::Unit() : m_index(0) , m_tu(0) , m_managementOptions(0) -{ -} - -static const int DisplayDiagnostics = qgetenv("QTC_CLANG_VERBOSE").isEmpty() ? 0 : 1; +{} -UnitData::UnitData(const QString &fileName) +Unit::Unit(const QString &fileName) : m_index(clang_createIndex(/*excludeDeclsFromPCH*/ 1, DisplayDiagnostics)) , m_tu(0) , m_fileName(fileName.toUtf8()) , m_managementOptions(0) -{ -} +{} -UnitData::~UnitData() +Unit::~Unit() { unload(); clang_disposeIndex(m_index); m_index = 0; } -void UnitData::swap(UnitData *other) -{ - qSwap(m_index, other->m_index); - qSwap(m_tu, other->m_tu); - qSwap(m_fileName, other->m_fileName); - qSwap(m_compOptions, other->m_compOptions); - qSwap(m_sharedCompOptions, other->m_sharedCompOptions); - qSwap(m_managementOptions, other->m_managementOptions); - qSwap(m_unsaved, other->m_unsaved); - qSwap(m_timeStamp, other->m_timeStamp); -} - -void UnitData::unload() -{ - if (m_tu) { - clang_disposeTranslationUnit(m_tu); - m_tu = 0; - -#ifdef DEBUG_UNIT_COUNT - qDebug() << "# translation units:" << (unitDataCount.fetchAndAddOrdered(-1) - 1); -#endif // DEBUG_UNIT_COUNT - } -} - -bool UnitData::isLoaded() const -{ - return m_tu && m_index; -} - -void UnitData::updateTimeStamp() +Unit::Ptr Unit::create() { - m_timeStamp = QDateTime::currentDateTime(); + return Unit::Ptr(new Unit); } -Unit::Unit() - : m_data(new UnitData) -{} - -Unit::Unit(const QString &fileName) - : m_data(new UnitData(fileName)) -{} - -Unit::Unit(const Unit &unit) - : m_data(unit.m_data) -{} - -Unit &Unit::operator =(const Unit &unit) +Unit::Ptr Unit::create(const QString &fileName) { - if (this != &unit) - m_data = unit.m_data; - return *this; + return Unit::Ptr(new Unit(fileName)); } -Unit::~Unit() -{} - const QString Unit::fileName() const { - const QByteArray &name = m_data->m_fileName; - return QString::fromUtf8(name.data(), name.size()); + return QString::fromUtf8(m_fileName.data(), m_fileName.size()); } bool Unit::isLoaded() const { - return m_data->isLoaded(); + return m_tu && m_index; } const QDateTime &Unit::timeStamp() const { - return m_data->m_timeStamp; + return m_timeStamp; } QStringList Unit::compilationOptions() const { - return m_data->m_compOptions; + return m_compOptions; } void Unit::setCompilationOptions(const QStringList &compOptions) { - m_data->m_compOptions = compOptions; - m_data->m_sharedCompOptions.reloadOptions(compOptions); + m_compOptions = compOptions; + m_sharedCompOptions.reloadOptions(compOptions); } UnsavedFiles Unit::unsavedFiles() const { - return m_data->m_unsaved; + return m_unsaved; } void Unit::setUnsavedFiles(const UnsavedFiles &unsavedFiles) { - m_data->m_unsaved = unsavedFiles; + m_unsaved = unsavedFiles; } unsigned Unit::managementOptions() const { - return m_data->m_managementOptions; + return m_managementOptions; } void Unit::setManagementOptions(unsigned managementOptions) { - m_data->m_managementOptions = managementOptions; -} - -bool Unit::isUnique() const -{ -#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) - return m_data->ref.load() == 1; -#else - return m_data->ref == 1; -#endif -} - -void Unit::makeUnique() -{ - UnitData *uniqueData = new UnitData; - m_data->swap(uniqueData); // Notice we swap the data itself and not the shared pointer. - m_data = QExplicitlySharedDataPointer<UnitData>(uniqueData); + m_managementOptions = managementOptions; } void Unit::parse() { - m_data->unload(); + unload(); - m_data->updateTimeStamp(); + updateTimeStamp(); - UnsavedFileData unsaved(m_data->m_unsaved); - m_data->m_tu = clang_parseTranslationUnit(m_data->m_index, - m_data->m_fileName.constData(), - m_data->m_sharedCompOptions.data(), - m_data->m_sharedCompOptions.size(), - unsaved.files(), - unsaved.count(), - m_data->m_managementOptions); + UnsavedFileData unsaved(m_unsaved); + m_tu = clang_parseTranslationUnit(m_index, m_fileName.constData(), + m_sharedCompOptions.data(), m_sharedCompOptions.size(), + unsaved.files(), unsaved.count(), + m_managementOptions); } void Unit::reparse() { Q_ASSERT(isLoaded()); - UnsavedFileData unsaved(m_data->m_unsaved); - const unsigned opts = clang_defaultReparseOptions(m_data->m_tu); - if (clang_reparseTranslationUnit(m_data->m_tu, unsaved.count(), unsaved.files(), opts) != 0) - m_data->unload(); -} - -void Unit::create() -{ - // @TODO -} - -void Unit::createFromSourceFile() -{ - // @TODO + UnsavedFileData unsaved(m_unsaved); + const unsigned opts = clang_defaultReparseOptions(m_tu); + if (clang_reparseTranslationUnit(m_tu, unsaved.count(), unsaved.files(), opts) != 0) + unload(); } int Unit::save(const QString &unitFileName) { Q_ASSERT(isLoaded()); - return clang_saveTranslationUnit(m_data->m_tu, - unitFileName.toUtf8().constData(), - clang_defaultSaveOptions(m_data->m_tu)); + return clang_saveTranslationUnit(m_tu, unitFileName.toUtf8().constData(), + clang_defaultSaveOptions(m_tu)); } void Unit::unload() { - m_data->unload(); + if (m_tu) { + clang_disposeTranslationUnit(m_tu); + m_tu = 0; + +#ifdef DEBUG_UNIT_COUNT + qDebug() << "# translation units:" << (unitDataCount.fetchAndAddOrdered(-1) - 1); +#endif // DEBUG_UNIT_COUNT + } } CXFile Unit::getFile() const { Q_ASSERT(isLoaded()); - return clang_getFile(m_data->m_tu, m_data->m_fileName.constData()); + return clang_getFile(m_tu, m_fileName.constData()); } CXCursor Unit::getCursor(const CXSourceLocation &location) const { Q_ASSERT(isLoaded()); - return clang_getCursor(m_data->m_tu, location); + return clang_getCursor(m_tu, location); } CXSourceLocation Unit::getLocation(const CXFile &file, unsigned line, unsigned column) const { Q_ASSERT(isLoaded()); - return clang_getLocation(m_data->m_tu, file, line, column); + return clang_getLocation(m_tu, file, line, column); } void Unit::codeCompleteAt(unsigned line, unsigned column, ScopedCXCodeCompleteResults &results) @@ -300,10 +196,11 @@ void Unit::codeCompleteAt(unsigned line, unsigned column, ScopedCXCodeCompleteRe flags |= CXCodeComplete_IncludeBriefComments; #endif - UnsavedFileData unsaved(m_data->m_unsaved); - results.reset(clang_codeCompleteAt(m_data->m_tu, m_data->m_fileName.constData(), + UnsavedFileData unsaved(m_unsaved); + results.reset(clang_codeCompleteAt(m_tu, m_fileName.constData(), line, column, - unsaved.files(), unsaved.count(), flags)); + unsaved.files(), unsaved.count(), + flags)); } void Unit::tokenize(CXSourceRange range, CXToken **tokens, unsigned *tokenCount) const @@ -313,21 +210,21 @@ void Unit::tokenize(CXSourceRange range, CXToken **tokens, unsigned *tokenCount) Q_ASSERT(tokenCount); Q_ASSERT(!clang_Range_isNull(range)); - clang_tokenize(m_data->m_tu, range, tokens, tokenCount); + clang_tokenize(m_tu, range, tokens, tokenCount); } void Unit::disposeTokens(CXToken *tokens, unsigned tokenCount) const { Q_ASSERT(isLoaded()); - clang_disposeTokens(m_data->m_tu, tokens, tokenCount); + clang_disposeTokens(m_tu, tokens, tokenCount); } CXSourceRange Unit::getTokenExtent(const CXToken &token) const { Q_ASSERT(isLoaded()); - return clang_getTokenExtent(m_data->m_tu, token); + return clang_getTokenExtent(m_tu, token); } void Unit::annotateTokens(CXToken *tokens, unsigned tokenCount, CXCursor *cursors) const @@ -336,63 +233,68 @@ void Unit::annotateTokens(CXToken *tokens, unsigned tokenCount, CXCursor *cursor Q_ASSERT(tokens); Q_ASSERT(cursors); - clang_annotateTokens(m_data->m_tu, tokens, tokenCount, cursors); + clang_annotateTokens(m_tu, tokens, tokenCount, cursors); } CXTranslationUnit Unit::clangTranslationUnit() const { Q_ASSERT(isLoaded()); - return m_data->m_tu; + return m_tu; } CXIndex Unit::clangIndex() const { Q_ASSERT(isLoaded()); - return m_data->m_index; + return m_index; } QString Unit::getTokenSpelling(const CXToken &tok) const { Q_ASSERT(isLoaded()); - return getQString(clang_getTokenSpelling(m_data->m_tu, tok)); + return getQString(clang_getTokenSpelling(m_tu, tok)); } CXCursor Unit::getTranslationUnitCursor() const { Q_ASSERT(isLoaded()); - return clang_getTranslationUnitCursor(m_data->m_tu); + return clang_getTranslationUnitCursor(m_tu); } CXString Unit::getTranslationUnitSpelling() const { Q_ASSERT(isLoaded()); - return clang_getTranslationUnitSpelling(m_data->m_tu); + return clang_getTranslationUnitSpelling(m_tu); } void Unit::getInclusions(CXInclusionVisitor visitor, CXClientData clientData) const { Q_ASSERT(isLoaded()); - clang_getInclusions(m_data->m_tu, visitor, clientData); + clang_getInclusions(m_tu, visitor, clientData); } unsigned Unit::getNumDiagnostics() const { Q_ASSERT(isLoaded()); - return clang_getNumDiagnostics(m_data->m_tu); + return clang_getNumDiagnostics(m_tu); } CXDiagnostic Unit::getDiagnostic(unsigned index) const { Q_ASSERT(isLoaded()); - return clang_getDiagnostic(m_data->m_tu, index); + return clang_getDiagnostic(m_tu, index); +} + +void Unit::updateTimeStamp() +{ + m_timeStamp = QDateTime::currentDateTime(); } IdentifierTokens::IdentifierTokens(const Unit &unit, unsigned firstLine, unsigned lastLine) diff --git a/src/plugins/clangcodemodel/unit.h b/src/plugins/clangcodemodel/unit.h index ef197a4b96..7326040128 100644 --- a/src/plugins/clangcodemodel/unit.h +++ b/src/plugins/clangcodemodel/unit.h @@ -31,10 +31,11 @@ #define UNIT_H #include "utils.h" - +#include "raii/scopedclangoptions.h" #include "cxraii.h" -#include <QExplicitlySharedDataPointer> +#include <QtCore/QDateTime> +#include <QSharedPointer> #include <QMetaType> #include <QString> #include <QStringList> @@ -63,8 +64,6 @@ class UnitData; * - This class is not thread-safe. * - It's responsibility of the client to make sure that the wrapped translation * unit is consistent with the other data such as cursor and locations being used. - * - The data of the TU is shared. - * * * @TODO: This is similar but not exactly the same as the current ClangWrapper class. * That class is now tuned to specific features, so it's not generic enough to be used @@ -74,13 +73,18 @@ class UnitData; */ class Unit { -public: + Q_DISABLE_COPY(Unit) + Unit(); explicit Unit(const QString &fileName); - Unit(const Unit &unit); - Unit &operator=(const Unit &unit); + +public: ~Unit(); + typedef QSharedPointer<Unit> Ptr; + static Ptr create(); + static Ptr create(const QString &fileName); + bool isLoaded() const; const QString fileName() const; @@ -96,20 +100,11 @@ public: unsigned managementOptions() const; void setManagementOptions(unsigned managementOptions); - // Sharing control facilities - // Method isUnique is just like an "isDetached", however makeUnique is mostly some kind - // of "detach" but which actually moves the data to this particular instance, invalidating - // then all the other shares. - bool isUnique() const; - void makeUnique(); - // Methods for generating the TU. Name mappings are direct, for example: // - parse corresponds to clang_parseTranslationUnit // - createFromSourceFile corresponds to clang_createTranslationUnitFromSourceFile void parse(); void reparse(); - void create(); - void createFromSourceFile(); int save(const QString &unitFileName); void unload(); @@ -152,7 +147,16 @@ public: QString getTokenSpelling(const CXToken &tok) const; private: - QExplicitlySharedDataPointer<UnitData> m_data; + void updateTimeStamp(); + + CXIndex m_index; + CXTranslationUnit m_tu; + QByteArray m_fileName; + QStringList m_compOptions; + SharedClangOptions m_sharedCompOptions; + unsigned m_managementOptions; + UnsavedFiles m_unsaved; + QDateTime m_timeStamp; }; class IdentifierTokens @@ -190,6 +194,6 @@ private: } // Internal } // Clang -Q_DECLARE_METATYPE(ClangCodeModel::Internal::Unit) +Q_DECLARE_METATYPE(ClangCodeModel::Internal::Unit::Ptr) #endif // UNIT_H diff --git a/src/plugins/clangcodemodel/utils.cpp b/src/plugins/clangcodemodel/utils.cpp index d057700c4f..6b2872718e 100644 --- a/src/plugins/clangcodemodel/utils.cpp +++ b/src/plugins/clangcodemodel/utils.cpp @@ -48,16 +48,16 @@ QPair<bool, QStringList> precompile(const PchInfo::Ptr &pchInfo) bool ok = false; - Internal::Unit unit(pchInfo->inputFileName()); - unit.setCompilationOptions(pchInfo->options()); + Internal::Unit::Ptr unit = Internal::Unit::create(pchInfo->inputFileName()); + unit->setCompilationOptions(pchInfo->options()); unsigned parseOpts = CXTranslationUnit_ForSerialization | CXTranslationUnit_Incomplete; - unit.setManagementOptions(parseOpts); + unit->setManagementOptions(parseOpts); - unit.parse(); - if (unit.isLoaded()) - ok = CXSaveError_None == unit.save(pchInfo->fileName()); + unit->parse(); + if (unit->isLoaded()) + ok = CXSaveError_None == unit->save(pchInfo->fileName()); return qMakePair(ok, Internal::formattedDiagnostics(unit)); } diff --git a/src/plugins/clangcodemodel/utils_p.cpp b/src/plugins/clangcodemodel/utils_p.cpp index 7883186d59..c9658d9f38 100644 --- a/src/plugins/clangcodemodel/utils_p.cpp +++ b/src/plugins/clangcodemodel/utils_p.cpp @@ -96,15 +96,15 @@ QString normalizeFileName(const QFileInfo &fileInfo) return QDir::cleanPath(fileInfo.absoluteFilePath()); } -QStringList formattedDiagnostics(const Unit &unit) +QStringList formattedDiagnostics(const Unit::Ptr &unit) { QStringList diags; - if (!unit.isLoaded()) + if (!unit->isLoaded()) return diags; - const unsigned count = unit.getNumDiagnostics(); + const unsigned count = unit->getNumDiagnostics(); for (unsigned i = 0; i < count; ++i) { - CXDiagnostic diag = unit.getDiagnostic(i); + CXDiagnostic diag = unit->getDiagnostic(i); unsigned opt = CXDiagnostic_DisplaySourceLocation | CXDiagnostic_DisplayColumn diff --git a/src/plugins/clangcodemodel/utils_p.h b/src/plugins/clangcodemodel/utils_p.h index 7078ce9786..d352d4a484 100644 --- a/src/plugins/clangcodemodel/utils_p.h +++ b/src/plugins/clangcodemodel/utils_p.h @@ -31,6 +31,7 @@ #define CLANG_REUSE_H #include "sourcelocation.h" +#include "unit.h" #include <clang-c/Index.h> @@ -43,8 +44,6 @@ QT_END_NAMESPACE namespace ClangCodeModel { namespace Internal { -class Unit; - QString getQString(const CXString &cxString, bool disposeCXString = true); SourceLocation getInstantiatonLocation(const CXSourceLocation &loc); // Deprecated @@ -58,7 +57,7 @@ SourceLocation getExpansionLocation(const CXSourceLocation &loc); QString normalizeFileName(const QString &fileName); QString normalizeFileName(const QFileInfo &fileInfo); -QStringList formattedDiagnostics(const Unit &unit); +QStringList formattedDiagnostics(const Unit::Ptr &unit); } // Internal } // ClangCodeModel |