Commit a4b6e35a authored by Erik Verbruggen's avatar Erik Verbruggen Committed by Nikolai Kosjar

Clang: clean up unit handling.

- Use a QSharedPointer instead of an explicitly shared pointer.
- Remove the LiveUnitManager.

Change-Id: I05bf32c1f77c17f42ee1da39f1353cff580fa6eb
Reviewed-by: default avatarNikolai Kosjar <nikolai.kosjar@digia.com>
parent 22519583
......@@ -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 \
......
......@@ -163,8 +163,6 @@ QtcPlugin {
"diagnostic.h",
"fastindexer.cpp",
"fastindexer.h",
"liveunitsmanager.cpp",
"liveunitsmanager.h",
"pchinfo.cpp",
"pchinfo.h",
"pchmanager.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;
......
......@@ -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;
......
......@@ -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);
}
......
......@@ -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;
......
......@@ -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);
......
......@@ -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
......
......@@ -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);
}
......
......@@ -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);
......
/****************************************************************************
**
** 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());
}
/****************************************************************************
**
** 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
......@@ -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;
}
......@@ -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
......
This diff is collapsed.
......@@ -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
......@@ -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));
}
......
......@@ -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
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment