forked from qt-creator/qt-creator
Clang: Do not call DocumentManager::modifiedDocuments() from worker thread
This is unsafe. Change-Id: I8ac075a7289afa0d84785e37b1325d186a153000 Reviewed-by: Erik Verbruggen <erik.verbruggen@theqtcompany.com>
This commit is contained in:
@@ -33,6 +33,7 @@
|
|||||||
#include "clangutils.h"
|
#include "clangutils.h"
|
||||||
|
|
||||||
#include <cpptools/cppmodelmanager.h>
|
#include <cpptools/cppmodelmanager.h>
|
||||||
|
#include <cpptools/cpptoolsreuse.h>
|
||||||
#include <cpptools/cppworkingcopy.h>
|
#include <cpptools/cppworkingcopy.h>
|
||||||
|
|
||||||
#include <texteditor/texteditor.h>
|
#include <texteditor/texteditor.h>
|
||||||
@@ -58,7 +59,9 @@ ClangCompletionAssistInterface::ClangCompletionAssistInterface(
|
|||||||
, m_languageFeatures(features)
|
, m_languageFeatures(features)
|
||||||
, m_textEditorWidget(textEditorWidget)
|
, m_textEditorWidget(textEditorWidget)
|
||||||
{
|
{
|
||||||
m_unsavedFiles = Utils::createUnsavedFiles(CppTools::CppModelManager::instance()->workingCopy());
|
m_unsavedFiles = Utils::createUnsavedFiles(
|
||||||
|
CppTools::CppModelManager::instance()->workingCopy(),
|
||||||
|
CppTools::modifiedFiles());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ClangCompletionAssistInterface::objcEnabled() const
|
bool ClangCompletionAssistInterface::objcEnabled() const
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ ClangEditorDocumentParser::ClangEditorDocumentParser(const QString &filePath)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangEditorDocumentParser::updateHelper(CppTools::WorkingCopy workingCopy)
|
void ClangEditorDocumentParser::updateHelper(const BaseEditorDocumentParser::InMemoryInfo &info)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_marker, return);
|
QTC_ASSERT(m_marker, return);
|
||||||
|
|
||||||
@@ -107,7 +107,8 @@ void ClangEditorDocumentParser::updateHelper(CppTools::WorkingCopy workingCopy)
|
|||||||
QMutexLocker lock(m_marker->mutex());
|
QMutexLocker lock(m_marker->mutex());
|
||||||
m_marker->setFileName(filePath());
|
m_marker->setFileName(filePath());
|
||||||
m_marker->setCompilationOptions(options);
|
m_marker->setCompilationOptions(options);
|
||||||
const Internal::UnsavedFiles unsavedFiles = Utils::createUnsavedFiles(workingCopy);
|
const Internal::UnsavedFiles unsavedFiles = Utils::createUnsavedFiles(info.workingCopy,
|
||||||
|
info.modifiedFiles);
|
||||||
m_marker->reparse(unsavedFiles);
|
m_marker->reparse(unsavedFiles);
|
||||||
qCDebug(log) << "Reparse took" << t.elapsed() << "ms.";
|
qCDebug(log) << "Reparse took" << t.elapsed() << "ms.";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ public:
|
|||||||
SemanticMarker::Ptr semanticMarker() const;
|
SemanticMarker::Ptr semanticMarker() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateHelper(CppTools::WorkingCopy workingCopy) override;
|
void updateHelper(const BaseEditorDocumentParser::InMemoryInfo &info) override;
|
||||||
|
|
||||||
SemanticMarker::Ptr m_marker;
|
SemanticMarker::Ptr m_marker;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -144,9 +144,6 @@ ClangEditorDocumentProcessor::~ClangEditorDocumentProcessor()
|
|||||||
void ClangEditorDocumentProcessor::run()
|
void ClangEditorDocumentProcessor::run()
|
||||||
{
|
{
|
||||||
// Run clang parser
|
// Run clang parser
|
||||||
const CppTools::WorkingCopy workingCopy
|
|
||||||
= CppTools::CppModelManager::instance()->workingCopy();
|
|
||||||
|
|
||||||
disconnect(&m_parserWatcher, &QFutureWatcher<void>::finished,
|
disconnect(&m_parserWatcher, &QFutureWatcher<void>::finished,
|
||||||
this, &ClangEditorDocumentProcessor::onParserFinished);
|
this, &ClangEditorDocumentProcessor::onParserFinished);
|
||||||
m_parserWatcher.cancel();
|
m_parserWatcher.cancel();
|
||||||
@@ -155,7 +152,9 @@ void ClangEditorDocumentProcessor::run()
|
|||||||
m_parserRevision = revision();
|
m_parserRevision = revision();
|
||||||
connect(&m_parserWatcher, &QFutureWatcher<void>::finished,
|
connect(&m_parserWatcher, &QFutureWatcher<void>::finished,
|
||||||
this, &ClangEditorDocumentProcessor::onParserFinished);
|
this, &ClangEditorDocumentProcessor::onParserFinished);
|
||||||
const QFuture<void> future = QtConcurrent::run(&runParser, parser(), workingCopy);
|
const QFuture<void> future = QtConcurrent::run(&runParser,
|
||||||
|
parser(),
|
||||||
|
ClangEditorDocumentParser::InMemoryInfo(true));
|
||||||
m_parserWatcher.setFuture(future);
|
m_parserWatcher.setFuture(future);
|
||||||
|
|
||||||
// Run builtin processor
|
// Run builtin processor
|
||||||
|
|||||||
@@ -32,7 +32,6 @@
|
|||||||
|
|
||||||
#include <clang-c/Index.h>
|
#include <clang-c/Index.h>
|
||||||
|
|
||||||
#include <coreplugin/documentmanager.h>
|
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <coreplugin/idocument.h>
|
#include <coreplugin/idocument.h>
|
||||||
|
|
||||||
@@ -58,15 +57,9 @@ namespace Utils {
|
|||||||
|
|
||||||
Q_LOGGING_CATEGORY(verboseRunLog, "qtc.clangcodemodel.verboserun")
|
Q_LOGGING_CATEGORY(verboseRunLog, "qtc.clangcodemodel.verboserun")
|
||||||
|
|
||||||
UnsavedFiles createUnsavedFiles(WorkingCopy workingCopy)
|
UnsavedFiles createUnsavedFiles(const WorkingCopy &workingCopy,
|
||||||
|
const ::Utils::FileNameList &modifiedFiles)
|
||||||
{
|
{
|
||||||
// TODO: change the modelmanager to hold one working copy, and amend it every time we ask for one.
|
|
||||||
// TODO: Reason: the UnsavedFile needs a QByteArray.
|
|
||||||
|
|
||||||
QSet< ::Utils::FileName> modifiedFiles;
|
|
||||||
foreach (IDocument *doc, DocumentManager::modifiedDocuments())
|
|
||||||
modifiedFiles.insert(doc->filePath());
|
|
||||||
|
|
||||||
UnsavedFiles result;
|
UnsavedFiles result;
|
||||||
QHashIterator< ::Utils::FileName, QPair<QByteArray, unsigned> > wcIter = workingCopy.iterator();
|
QHashIterator< ::Utils::FileName, QPair<QByteArray, unsigned> > wcIter = workingCopy.iterator();
|
||||||
while (wcIter.hasNext()) {
|
while (wcIter.hasNext()) {
|
||||||
|
|||||||
@@ -43,7 +43,9 @@ namespace Utils {
|
|||||||
|
|
||||||
Q_DECLARE_LOGGING_CATEGORY(verboseRunLog)
|
Q_DECLARE_LOGGING_CATEGORY(verboseRunLog)
|
||||||
|
|
||||||
ClangCodeModel::Internal::UnsavedFiles createUnsavedFiles(CppTools::WorkingCopy workingCopy);
|
ClangCodeModel::Internal::UnsavedFiles createUnsavedFiles(
|
||||||
|
const CppTools::WorkingCopy &workingCopy,
|
||||||
|
const ::Utils::FileNameList &modifiedFiles);
|
||||||
|
|
||||||
QStringList createClangOptions(const CppTools::ProjectPart::Ptr &pPart,
|
QStringList createClangOptions(const CppTools::ProjectPart::Ptr &pPart,
|
||||||
CppTools::ProjectFile::Kind fileKind);
|
CppTools::ProjectFile::Kind fileKind);
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
#include "baseeditordocumentparser.h"
|
#include "baseeditordocumentparser.h"
|
||||||
#include "baseeditordocumentprocessor.h"
|
#include "baseeditordocumentprocessor.h"
|
||||||
|
|
||||||
#include "cppworkingcopy.h"
|
#include "cpptoolsreuse.h"
|
||||||
#include "editordocumenthandle.h"
|
#include "editordocumenthandle.h"
|
||||||
|
|
||||||
namespace CppTools {
|
namespace CppTools {
|
||||||
@@ -81,10 +81,10 @@ void BaseEditorDocumentParser::setConfiguration(const Configuration &configurati
|
|||||||
m_configuration = configuration;
|
m_configuration = configuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseEditorDocumentParser::update(WorkingCopy workingCopy)
|
void BaseEditorDocumentParser::update(const InMemoryInfo &info)
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&m_updateIsRunning);
|
QMutexLocker locker(&m_updateIsRunning);
|
||||||
updateHelper(workingCopy);
|
updateHelper(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseEditorDocumentParser::State BaseEditorDocumentParser::state() const
|
BaseEditorDocumentParser::State BaseEditorDocumentParser::state() const
|
||||||
@@ -147,4 +147,11 @@ ProjectPart::Ptr BaseEditorDocumentParser::determineProjectPart(const QString &f
|
|||||||
return projectPart;
|
return projectPart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BaseEditorDocumentParser::InMemoryInfo::InMemoryInfo(bool withModifiedFiles)
|
||||||
|
: workingCopy(CppTools::CppModelManager::instance()->workingCopy())
|
||||||
|
{
|
||||||
|
if (withModifiedFiles)
|
||||||
|
modifiedFiles = CppTools::modifiedFiles();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace CppTools
|
} // namespace CppTools
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
#include "cppmodelmanager.h"
|
#include "cppmodelmanager.h"
|
||||||
#include "cpptools_global.h"
|
#include "cpptools_global.h"
|
||||||
|
#include "cppworkingcopy.h"
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
@@ -59,7 +60,13 @@ public:
|
|||||||
Configuration configuration() const;
|
Configuration configuration() const;
|
||||||
void setConfiguration(const Configuration &configuration);
|
void setConfiguration(const Configuration &configuration);
|
||||||
|
|
||||||
void update(WorkingCopy workingCopy);
|
struct CPPTOOLS_EXPORT InMemoryInfo {
|
||||||
|
InMemoryInfo(bool withModifiedFiles);
|
||||||
|
|
||||||
|
WorkingCopy workingCopy;
|
||||||
|
Utils::FileNameList modifiedFiles;
|
||||||
|
};
|
||||||
|
void update(const InMemoryInfo &info);
|
||||||
|
|
||||||
ProjectPart::Ptr projectPart() const;
|
ProjectPart::Ptr projectPart() const;
|
||||||
|
|
||||||
@@ -78,7 +85,7 @@ protected:
|
|||||||
mutable QMutex m_stateAndConfigurationMutex;
|
mutable QMutex m_stateAndConfigurationMutex;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void updateHelper(WorkingCopy workingCopy) = 0;
|
virtual void updateHelper(const InMemoryInfo &inMemoryInfo) = 0;
|
||||||
|
|
||||||
const QString m_filePath;
|
const QString m_filePath;
|
||||||
Configuration m_configuration;
|
Configuration m_configuration;
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
#include "baseeditordocumentprocessor.h"
|
#include "baseeditordocumentprocessor.h"
|
||||||
#include "cppworkingcopy.h"
|
#include "cppworkingcopy.h"
|
||||||
|
|
||||||
|
#include "cpptoolsreuse.h"
|
||||||
#include "editordocumenthandle.h"
|
#include "editordocumenthandle.h"
|
||||||
|
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
@@ -118,7 +119,7 @@ QList<QTextEdit::ExtraSelection> BaseEditorDocumentProcessor::toTextEditorSelect
|
|||||||
|
|
||||||
void BaseEditorDocumentProcessor::runParser(QFutureInterface<void> &future,
|
void BaseEditorDocumentProcessor::runParser(QFutureInterface<void> &future,
|
||||||
BaseEditorDocumentParser *parser,
|
BaseEditorDocumentParser *parser,
|
||||||
WorkingCopy workingCopy)
|
BaseEditorDocumentParser::InMemoryInfo info)
|
||||||
{
|
{
|
||||||
future.setProgressRange(0, 1);
|
future.setProgressRange(0, 1);
|
||||||
if (future.isCanceled()) {
|
if (future.isCanceled()) {
|
||||||
@@ -126,7 +127,7 @@ void BaseEditorDocumentProcessor::runParser(QFutureInterface<void> &future,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
parser->update(workingCopy);
|
parser->update(info);
|
||||||
CppModelManager::instance()
|
CppModelManager::instance()
|
||||||
->finishedRefreshingSourceFiles(QSet<QString>() << parser->filePath());
|
->finishedRefreshingSourceFiles(QSet<QString>() << parser->filePath());
|
||||||
|
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ protected:
|
|||||||
|
|
||||||
static void runParser(QFutureInterface<void> &future,
|
static void runParser(QFutureInterface<void> &future,
|
||||||
CppTools::BaseEditorDocumentParser *parser,
|
CppTools::BaseEditorDocumentParser *parser,
|
||||||
CppTools::WorkingCopy workingCopy);
|
BaseEditorDocumentParser::InMemoryInfo info);
|
||||||
|
|
||||||
// Convenience
|
// Convenience
|
||||||
QString filePath() const { return m_baseTextDocument->filePath().toString(); }
|
QString filePath() const { return m_baseTextDocument->filePath().toString(); }
|
||||||
|
|||||||
@@ -44,16 +44,17 @@ BuiltinEditorDocumentParser::BuiltinEditorDocumentParser(const QString &filePath
|
|||||||
qRegisterMetaType<CPlusPlus::Snapshot>("CPlusPlus::Snapshot");
|
qRegisterMetaType<CPlusPlus::Snapshot>("CPlusPlus::Snapshot");
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuiltinEditorDocumentParser::updateHelper(WorkingCopy workingCopy)
|
void BuiltinEditorDocumentParser::updateHelper(const InMemoryInfo &info)
|
||||||
{
|
{
|
||||||
|
if (filePath().isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
const Configuration baseConfig = configuration();
|
const Configuration baseConfig = configuration();
|
||||||
const bool releaseSourceAndAST_ = releaseSourceAndAST();
|
const bool releaseSourceAndAST_ = releaseSourceAndAST();
|
||||||
|
|
||||||
State baseState = state();
|
State baseState = state();
|
||||||
ExtraState state = extraState();
|
ExtraState state = extraState();
|
||||||
|
WorkingCopy workingCopy = info.workingCopy;
|
||||||
if (filePath().isEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
bool invalidateSnapshot = false, invalidateConfig = false, editorDefinesChanged_ = false;
|
bool invalidateSnapshot = false, invalidateConfig = false, editorDefinesChanged_ = false;
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ public:
|
|||||||
static BuiltinEditorDocumentParser *get(const QString &filePath);
|
static BuiltinEditorDocumentParser *get(const QString &filePath);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateHelper(WorkingCopy workingCopy) override;
|
void updateHelper(const InMemoryInfo &info) override;
|
||||||
void addFileAndDependencies(CPlusPlus::Snapshot *snapshot,
|
void addFileAndDependencies(CPlusPlus::Snapshot *snapshot,
|
||||||
QSet<Utils::FileName> *toRemove,
|
QSet<Utils::FileName> *toRemove,
|
||||||
const Utils::FileName &fileName) const;
|
const Utils::FileName &fileName) const;
|
||||||
|
|||||||
@@ -43,8 +43,8 @@
|
|||||||
#include <cplusplus/CppDocument.h>
|
#include <cplusplus/CppDocument.h>
|
||||||
#include <cplusplus/SimpleLexer.h>
|
#include <cplusplus/SimpleLexer.h>
|
||||||
|
|
||||||
#include <utils/QtConcurrentTools>
|
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
#include <utils/runextensions.h>
|
||||||
|
|
||||||
#include <QLoggingCategory>
|
#include <QLoggingCategory>
|
||||||
|
|
||||||
@@ -166,7 +166,9 @@ BuiltinEditorDocumentProcessor::~BuiltinEditorDocumentProcessor()
|
|||||||
|
|
||||||
void BuiltinEditorDocumentProcessor::run()
|
void BuiltinEditorDocumentProcessor::run()
|
||||||
{
|
{
|
||||||
m_parserFuture = QtConcurrent::run(&runParser, parser(), CppTools::CppModelManager::instance()->workingCopy());
|
m_parserFuture = QtConcurrent::run(&runParser,
|
||||||
|
parser(),
|
||||||
|
BuiltinEditorDocumentParser::InMemoryInfo(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseEditorDocumentParser *BuiltinEditorDocumentProcessor::parser()
|
BaseEditorDocumentParser *BuiltinEditorDocumentProcessor::parser()
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ void indexFindErrors(QFutureInterface<void> &future, const ParseParams params)
|
|||||||
// Parse the file as precisely as possible
|
// Parse the file as precisely as possible
|
||||||
BuiltinEditorDocumentParser parser(file);
|
BuiltinEditorDocumentParser parser(file);
|
||||||
parser.setReleaseSourceAndAST(false);
|
parser.setReleaseSourceAndAST(false);
|
||||||
parser.update(params.workingCopy);
|
parser.update(BuiltinEditorDocumentParser::InMemoryInfo(false));
|
||||||
CPlusPlus::Document::Ptr document = parser.document();
|
CPlusPlus::Document::Ptr document = parser.document();
|
||||||
QTC_ASSERT(document, return);
|
QTC_ASSERT(document, return);
|
||||||
|
|
||||||
|
|||||||
@@ -2188,7 +2188,7 @@ void CppCompletionAssistInterface::getCppSpecifics() const
|
|||||||
m_gotCppSpecifics = true;
|
m_gotCppSpecifics = true;
|
||||||
|
|
||||||
if (BuiltinEditorDocumentParser *parser = BuiltinEditorDocumentParser::get(fileName())) {
|
if (BuiltinEditorDocumentParser *parser = BuiltinEditorDocumentParser::get(fileName())) {
|
||||||
parser->update(m_workingCopy);
|
parser->update(BuiltinEditorDocumentParser::InMemoryInfo(false));
|
||||||
m_snapshot = parser->snapshot();
|
m_snapshot = parser->snapshot();
|
||||||
m_headerPaths = parser->headerPaths();
|
m_headerPaths = parser->headerPaths();
|
||||||
if (Document::Ptr document = parser->document())
|
if (Document::Ptr document = parser->document())
|
||||||
|
|||||||
@@ -915,7 +915,7 @@ void CppToolsPlugin::test_modelmanager_precompiled_headers()
|
|||||||
BaseEditorDocumentParser::Configuration config = parser->configuration();
|
BaseEditorDocumentParser::Configuration config = parser->configuration();
|
||||||
config.usePrecompiledHeaders = true;
|
config.usePrecompiledHeaders = true;
|
||||||
parser->setConfiguration(config);
|
parser->setConfiguration(config);
|
||||||
parser->update(mm->workingCopy());
|
parser->update(BuiltinEditorDocumentParser::InMemoryInfo(false));
|
||||||
|
|
||||||
// Check if defines from pch are considered
|
// Check if defines from pch are considered
|
||||||
Document::Ptr document = mm->document(fileName);
|
Document::Ptr document = mm->document(fileName);
|
||||||
@@ -998,8 +998,7 @@ void CppToolsPlugin::test_modelmanager_defines_per_editor()
|
|||||||
BaseEditorDocumentParser::Configuration config = parser->configuration();
|
BaseEditorDocumentParser::Configuration config = parser->configuration();
|
||||||
config.editorDefines = editorDefines.toUtf8();
|
config.editorDefines = editorDefines.toUtf8();
|
||||||
parser->setConfiguration(config);
|
parser->setConfiguration(config);
|
||||||
|
parser->update(BuiltinEditorDocumentParser::InMemoryInfo(false));
|
||||||
parser->update(mm->workingCopy());
|
|
||||||
|
|
||||||
Document::Ptr doc = mm->document(main1File);
|
Document::Ptr doc = mm->document(main1File);
|
||||||
QCOMPARE(nameOfFirstDeclaration(doc), firstDeclarationName);
|
QCOMPARE(nameOfFirstDeclaration(doc), firstDeclarationName);
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
#include "cpptoolsplugin.h"
|
#include "cpptoolsplugin.h"
|
||||||
|
|
||||||
|
#include <coreplugin/documentmanager.h>
|
||||||
#include <coreplugin/editormanager/editormanager.h>
|
#include <coreplugin/editormanager/editormanager.h>
|
||||||
#include <coreplugin/idocument.h>
|
#include <coreplugin/idocument.h>
|
||||||
#include <texteditor/convenience.h>
|
#include <texteditor/convenience.h>
|
||||||
@@ -287,4 +288,13 @@ bool skipFileDueToSizeLimit(const QFileInfo &fileInfo, int limitInMB)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Utils::FileNameList modifiedFiles()
|
||||||
|
{
|
||||||
|
Utils::FileNameList files;
|
||||||
|
foreach (Core::IDocument *doc, Core::DocumentManager::modifiedDocuments())
|
||||||
|
files.append(doc->filePath());
|
||||||
|
files.removeDuplicates();
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
} // CppTools
|
} // CppTools
|
||||||
|
|||||||
@@ -44,6 +44,10 @@ class QStringRef;
|
|||||||
class QTextCursor;
|
class QTextCursor;
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
namespace Utils {
|
||||||
|
class FileNameList;
|
||||||
|
} // namespace Utils
|
||||||
|
|
||||||
namespace CPlusPlus {
|
namespace CPlusPlus {
|
||||||
class Macro;
|
class Macro;
|
||||||
class Symbol;
|
class Symbol;
|
||||||
@@ -52,6 +56,8 @@ class LookupContext;
|
|||||||
|
|
||||||
namespace CppTools {
|
namespace CppTools {
|
||||||
|
|
||||||
|
Utils::FileNameList CPPTOOLS_EXPORT modifiedFiles();
|
||||||
|
|
||||||
void CPPTOOLS_EXPORT moveCursorToEndOfIdentifier(QTextCursor *tc);
|
void CPPTOOLS_EXPORT moveCursorToEndOfIdentifier(QTextCursor *tc);
|
||||||
void CPPTOOLS_EXPORT moveCursorToStartOfIdentifier(QTextCursor *tc);
|
void CPPTOOLS_EXPORT moveCursorToStartOfIdentifier(QTextCursor *tc);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user