Clang: Remove PchManager

...which is the last dependency to libclang from the plugin.

Change-Id: I173ee7e9621912ec88706b4cf62db2b1dbcf7610
Reviewed-by: Marco Bubke <marco.bubke@theqtcompany.com>
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@theqtcompany.com>
This commit is contained in:
Nikolai Kosjar
2015-11-27 18:21:46 +01:00
parent daf9369679
commit 5f98b8ec24
23 changed files with 10 additions and 1819 deletions

View File

@@ -34,7 +34,6 @@
#include "clangeditordocumentprocessor.h" #include "clangeditordocumentprocessor.h"
#include "clangmodelmanagersupport.h" #include "clangmodelmanagersupport.h"
#include "clangutils.h" #include "clangutils.h"
#include "pchmanager.h"
#include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
@@ -335,10 +334,8 @@ void IpcCommunicator::initializeBackend()
static QStringList projectPartOptions(const CppTools::ProjectPart::Ptr &projectPart) static QStringList projectPartOptions(const CppTools::ProjectPart::Ptr &projectPart)
{ {
QStringList options = ClangCodeModel::Utils::createClangOptions(projectPart, const QStringList options = ClangCodeModel::Utils::createClangOptions(projectPart,
CppTools::ProjectFile::Unclassified); // No language option CppTools::ProjectFile::Unclassified); // No language option
if (PchInfo::Ptr pchInfo = PchManager::instance()->pchInfo(projectPart))
options += ClangCodeModel::Utils::createPCHInclusionOptions(pchInfo->fileName());
return options; return options;
} }

View File

@@ -1,16 +1,12 @@
include(../../qtcreatorplugin.pri) include(../../qtcreatorplugin.pri)
include(../../shared/clang/clang_installation.pri) include(../../shared/clang/clang_installation.pri)
LIBS += $$LLVM_LIBS
INCLUDEPATH += $$LLVM_INCLUDEPATH
DEFINES += CLANGCODEMODEL_LIBRARY DEFINES += CLANGCODEMODEL_LIBRARY
# The following defines are used to determine the clang include path for intrinsics. # The following defines are used to determine the clang include path for intrinsics.
DEFINES += CLANG_VERSION=\\\"$${LLVM_VERSION}\\\" DEFINES += CLANG_VERSION=\\\"$${LLVM_VERSION}\\\"
DEFINES += "\"CLANG_RESOURCE_DIR=\\\"$${LLVM_LIBDIR}/clang/$${LLVM_VERSION}/include\\\"\"" DEFINES += "\"CLANG_RESOURCE_DIR=\\\"$${LLVM_LIBDIR}/clang/$${LLVM_VERSION}/include\\\"\""
unix:QMAKE_LFLAGS += -Wl,-rpath,\'$$LLVM_LIBDIR\'
SOURCES += \ SOURCES += \
activationsequencecontextprocessor.cpp \ activationsequencecontextprocessor.cpp \
activationsequenceprocessor.cpp \ activationsequenceprocessor.cpp \
@@ -36,12 +32,7 @@ SOURCES += \
clangtextmark.cpp \ clangtextmark.cpp \
clangutils.cpp \ clangutils.cpp \
completionchunkstotextconverter.cpp \ completionchunkstotextconverter.cpp \
highlightingmarksreporter.cpp \ highlightingmarksreporter.cpp
pchinfo.cpp \
pchmanager.cpp \
raii/scopedclangoptions.cpp \
unit.cpp \
unsavedfiledata.cpp
HEADERS += \ HEADERS += \
activationsequencecontextprocessor.h \ activationsequencecontextprocessor.h \
@@ -70,12 +61,7 @@ HEADERS += \
clangutils.h \ clangutils.h \
completionchunkstotextconverter.h \ completionchunkstotextconverter.h \
constants.h \ constants.h \
highlightingmarksreporter.h \ highlightingmarksreporter.h
pchinfo.h \
pchmanager.h \
raii/scopedclangoptions.h \
unit.h \
unsavedfiledata.h
FORMS += clangprojectsettingspropertiespage.ui FORMS += clangprojectsettingspropertiespage.ui

View File

@@ -23,16 +23,10 @@ QtcPlugin {
property string llvmConfig: Clang.llvmConfig(qbs, QtcFunctions, QtcProcessOutputReader) property string llvmConfig: Clang.llvmConfig(qbs, QtcFunctions, QtcProcessOutputReader)
property string llvmIncludeDir: Clang.includeDir(llvmConfig, QtcProcessOutputReader) property string llvmIncludeDir: Clang.includeDir(llvmConfig, QtcProcessOutputReader)
property string llvmLibDir: Clang.libDir(llvmConfig, QtcProcessOutputReader) property string llvmLibDir: Clang.libDir(llvmConfig, QtcProcessOutputReader)
property string llvmLibs: Clang.libraries(qbs.targetOS)
property string llvmVersion: Clang.version(llvmConfig, QtcProcessOutputReader) property string llvmVersion: Clang.version(llvmConfig, QtcProcessOutputReader)
condition: llvmConfig && File.exists(llvmIncludeDir.concat("/clang-c/Index.h")) condition: llvmConfig && File.exists(llvmIncludeDir.concat("/clang-c/Index.h"))
cpp.includePaths: base.concat(llvmIncludeDir)
cpp.libraryPaths: base.concat(llvmLibDir)
cpp.rpaths: cpp.libraryPaths
cpp.dynamicLibraries: base.concat(llvmLibs)
cpp.defines: { cpp.defines: {
var defines = base; var defines = base;
// The following defines are used to determine the clang include path for intrinsics. // The following defines are used to determine the clang include path for intrinsics.
@@ -95,16 +89,6 @@ QtcPlugin {
"constants.h", "constants.h",
"highlightingmarksreporter.cpp", "highlightingmarksreporter.cpp",
"highlightingmarksreporter.h", "highlightingmarksreporter.h",
"pchinfo.cpp",
"pchinfo.h",
"pchmanager.cpp",
"pchmanager.h",
"raii/scopedclangoptions.cpp",
"raii/scopedclangoptions.h",
"unit.cpp",
"unit.h",
"unsavedfiledata.cpp",
"unsavedfiledata.h",
] ]
Group { Group {

View File

@@ -32,7 +32,6 @@
#include "clangprojectsettingspropertiespage.h" #include "clangprojectsettingspropertiespage.h"
#include "constants.h" #include "constants.h"
#include "pchmanager.h"
#ifdef WITH_TESTS #ifdef WITH_TESTS
# include "test/clangcodecompletion_test.h" # include "test/clangcodecompletion_test.h"
@@ -46,8 +45,6 @@
#include <texteditor/textmark.h> #include <texteditor/textmark.h>
#include <clang-c/Index.h>
namespace ClangCodeModel { namespace ClangCodeModel {
namespace Internal { namespace Internal {
@@ -61,23 +58,6 @@ void initializeTextMarks()
Utils::Theme::ClangCodeModel_Error_TextMarkColor); Utils::Theme::ClangCodeModel_Error_TextMarkColor);
} }
static bool clangInitialised = false;
static QMutex initialisationMutex;
void initializeClang()
{
if (clangInitialised)
return;
QMutexLocker locker(&initialisationMutex);
if (clangInitialised)
return;
clang_toggleCrashRecovery(1);
clang_enableStackTraces();
clangInitialised = true;
}
} // anonymous namespace } // anonymous namespace
bool ClangCodeModelPlugin::initialize(const QStringList &arguments, QString *errorMessage) bool ClangCodeModelPlugin::initialize(const QStringList &arguments, QString *errorMessage)
@@ -92,19 +72,8 @@ bool ClangCodeModelPlugin::initialize(const QStringList &arguments, QString *err
panelFactory->setSimpleCreateWidgetFunction<ClangProjectSettingsWidget>(QIcon()); panelFactory->setSimpleCreateWidgetFunction<ClangProjectSettingsWidget>(QIcon());
ProjectExplorer::ProjectPanelFactory::registerFactory(panelFactory); ProjectExplorer::ProjectPanelFactory::registerFactory(panelFactory);
// Initialize Clang
ClangCodeModel::Internal::initializeClang();
// Set up PchManager
PchManager *pchManager = new PchManager(this);
ProjectExplorer::SessionManager *sessionManager = ProjectExplorer::SessionManager::instance();
connect(sessionManager, &ProjectExplorer::SessionManager::aboutToRemoveProject,
pchManager, &PchManager::onAboutToRemoveProject);
auto cppModelManager = CppTools::CppModelManager::instance();
connect(cppModelManager, &CppTools::CppModelManager::projectPartsUpdated,
pchManager, &PchManager::onProjectPartsUpdated);
// Register ModelManagerSupportProvider // Register ModelManagerSupportProvider
auto cppModelManager = CppTools::CppModelManager::instance();
cppModelManager->setClangModelManagerSupportProvider(&m_modelManagerSupportProvider); cppModelManager->setClangModelManagerSupportProvider(&m_modelManagerSupportProvider);
initializeTextMarks(); initializeTextMarks();

View File

@@ -32,14 +32,10 @@
#include "clangutils.h" #include "clangutils.h"
#include <cpptools/cppmodelmanager.h>
#include <cpptools/cpptoolsreuse.h> #include <cpptools/cpptoolsreuse.h>
#include <cpptools/cppworkingcopy.h>
#include <texteditor/texteditor.h> #include <texteditor/texteditor.h>
#include <cplusplus/Token.h>
namespace ClangCodeModel { namespace ClangCodeModel {
namespace Internal { namespace Internal {
@@ -50,18 +46,13 @@ ClangCompletionAssistInterface::ClangCompletionAssistInterface(
const QString &fileName, const QString &fileName,
TextEditor::AssistReason reason, TextEditor::AssistReason reason,
const CppTools::ProjectPart::HeaderPaths &headerPaths, const CppTools::ProjectPart::HeaderPaths &headerPaths,
const PchInfo::Ptr &pchInfo,
const CPlusPlus::LanguageFeatures &features) const CPlusPlus::LanguageFeatures &features)
: AssistInterface(textEditorWidget->document(), position, fileName, reason) : AssistInterface(textEditorWidget->document(), position, fileName, reason)
, m_ipcCommunicator(ipcCommunicator) , m_ipcCommunicator(ipcCommunicator)
, m_headerPaths(headerPaths) , m_headerPaths(headerPaths)
, m_savedPchPointer(pchInfo)
, m_languageFeatures(features) , m_languageFeatures(features)
, m_textEditorWidget(textEditorWidget) , m_textEditorWidget(textEditorWidget)
{ {
m_unsavedFiles = Utils::createUnsavedFiles(
CppTools::CppModelManager::instance()->workingCopy(),
CppTools::modifiedFiles());
} }
bool ClangCompletionAssistInterface::objcEnabled() const bool ClangCompletionAssistInterface::objcEnabled() const
@@ -94,11 +85,6 @@ IpcCommunicator &ClangCompletionAssistInterface::ipcCommunicator() const
return m_ipcCommunicator; return m_ipcCommunicator;
} }
const Utils::UnsavedFiles &ClangCompletionAssistInterface::unsavedFiles() const
{
return m_unsavedFiles;
}
} // namespace Internal } // namespace Internal
} // namespace ClangCodeModel } // namespace ClangCodeModel

View File

@@ -32,7 +32,6 @@
#define CLANGCODEMODEL_INTERNAL_CLANGCOMPLETIONASSISTINTERFACE_H #define CLANGCODEMODEL_INTERNAL_CLANGCOMPLETIONASSISTINTERFACE_H
#include "clangbackendipcintegration.h" #include "clangbackendipcintegration.h"
#include "pchinfo.h"
#include "clangutils.h" #include "clangutils.h"
#include <cpptools/cppcompletionassistprovider.h> #include <cpptools/cppcompletionassistprovider.h>
@@ -51,11 +50,9 @@ public:
const QString &fileName, const QString &fileName,
TextEditor::AssistReason reason, TextEditor::AssistReason reason,
const CppTools::ProjectPart::HeaderPaths &headerPaths, const CppTools::ProjectPart::HeaderPaths &headerPaths,
const PchInfo::Ptr &pchInfo,
const CPlusPlus::LanguageFeatures &features); const CPlusPlus::LanguageFeatures &features);
IpcCommunicator &ipcCommunicator() const; IpcCommunicator &ipcCommunicator() const;
const Utils::UnsavedFiles &unsavedFiles() const;
bool objcEnabled() const; bool objcEnabled() const;
const CppTools::ProjectPart::HeaderPaths &headerPaths() const; const CppTools::ProjectPart::HeaderPaths &headerPaths() const;
CPlusPlus::LanguageFeatures languageFeatures() const; CPlusPlus::LanguageFeatures languageFeatures() const;
@@ -65,10 +62,8 @@ public:
private: private:
IpcCommunicator &m_ipcCommunicator; IpcCommunicator &m_ipcCommunicator;
Utils::UnsavedFiles m_unsavedFiles;
QStringList m_options; QStringList m_options;
CppTools::ProjectPart::HeaderPaths m_headerPaths; CppTools::ProjectPart::HeaderPaths m_headerPaths;
Internal::PchInfo::Ptr m_savedPchPointer;
CPlusPlus::LanguageFeatures m_languageFeatures; CPlusPlus::LanguageFeatures m_languageFeatures;
const TextEditor::TextEditorWidget *m_textEditorWidget; const TextEditor::TextEditorWidget *m_textEditorWidget;
}; };

View File

@@ -33,7 +33,6 @@
#include "clangcompletionassistprocessor.h" #include "clangcompletionassistprocessor.h"
#include "clangeditordocumentprocessor.h" #include "clangeditordocumentprocessor.h"
#include "clangutils.h" #include "clangutils.h"
#include "pchmanager.h"
#include <cplusplus/Token.h> #include <cplusplus/Token.h>
#include <cpptools/cppcompletionassistprocessor.h> #include <cpptools/cppcompletionassistprocessor.h>
@@ -73,14 +72,12 @@ TextEditor::AssistInterface *ClangCompletionAssistProvider::createAssistInterfac
{ {
const CppTools::ProjectPart::Ptr projectPart = Utils::projectPartForFileBasedOnProcessor(filePath); const CppTools::ProjectPart::Ptr projectPart = Utils::projectPartForFileBasedOnProcessor(filePath);
if (projectPart) { if (projectPart) {
const PchInfo::Ptr pchInfo = PchManager::instance()->pchInfo(projectPart);
return new ClangCompletionAssistInterface(m_ipcCommunicator, return new ClangCompletionAssistInterface(m_ipcCommunicator,
textEditorWidget, textEditorWidget,
position, position,
filePath, filePath,
reason, reason,
projectPart->headerPaths, projectPart->headerPaths,
pchInfo,
projectPart->languageFeatures); projectPart->languageFeatures);
} }

View File

@@ -35,7 +35,6 @@
#include "clangmodelmanagersupport.h" #include "clangmodelmanagersupport.h"
#include "clangutils.h" #include "clangutils.h"
#include "highlightingmarksreporter.h" #include "highlightingmarksreporter.h"
#include "pchinfo.h"
#include <diagnosticcontainer.h> #include <diagnosticcontainer.h>
#include <sourcelocationcontainer.h> #include <sourcelocationcontainer.h>

View File

@@ -30,11 +30,6 @@
#include "clangprojectsettings.h" #include "clangprojectsettings.h"
#include "clangprojectsettingspropertiespage.h" #include "clangprojectsettingspropertiespage.h"
#include "pchmanager.h"
#include <QButtonGroup>
#include <QCoreApplication>
#include <QFileDialog>
using namespace ProjectExplorer; using namespace ProjectExplorer;
using namespace ClangCodeModel::Internal; using namespace ClangCodeModel::Internal;
@@ -43,88 +38,4 @@ ClangProjectSettingsWidget::ClangProjectSettingsWidget(Project *project)
: m_project(project) : m_project(project)
{ {
m_ui.setupUi(this); m_ui.setupUi(this);
ClangProjectSettings *cps = PchManager::instance()->settingsForProject(project);
Q_ASSERT(cps);
QButtonGroup *pchGroup = new QButtonGroup(this);
pchGroup->addButton(m_ui.noneButton, ClangProjectSettings::PchUse_None);
pchGroup->addButton(m_ui.exactButton, ClangProjectSettings::PchUse_BuildSystem_Exact);
pchGroup->addButton(m_ui.fuzzyButton, ClangProjectSettings::PchUse_BuildSystem_Fuzzy);
pchGroup->addButton(m_ui.customButton, ClangProjectSettings::PchUse_Custom);
switch (cps->pchUsage()) {
case ClangProjectSettings::PchUse_None:
case ClangProjectSettings::PchUse_BuildSystem_Exact:
case ClangProjectSettings::PchUse_BuildSystem_Fuzzy:
case ClangProjectSettings::PchUse_Custom:
pchGroup->button(cps->pchUsage())->setChecked(true);
break;
default: break;
}
pchUsageChanged(cps->pchUsage());
connect(pchGroup, SIGNAL(buttonClicked(int)),
this, SLOT(pchUsageChanged(int)));
m_ui.customField->setText(cps->customPchFile());
connect(m_ui.customField, SIGNAL(editingFinished()),
this, SLOT(customPchFileChanged()));
connect(m_ui.customButton, SIGNAL(clicked()),
this, SLOT(customPchButtonClicked()));
}
void ClangProjectSettingsWidget::pchUsageChanged(int id)
{
ClangProjectSettings *cps = PchManager::instance()->settingsForProject(m_project);
Q_ASSERT(cps);
cps->setPchUsage(static_cast<ClangProjectSettings::PchUsage>(id));
switch (id) {
case ClangProjectSettings::PchUse_None:
case ClangProjectSettings::PchUse_BuildSystem_Fuzzy:
case ClangProjectSettings::PchUse_BuildSystem_Exact:
m_ui.customField->setEnabled(false);
m_ui.chooseButton->setEnabled(false);
break;
case ClangProjectSettings::PchUse_Custom:
m_ui.customField->setEnabled(true);
m_ui.chooseButton->setEnabled(true);
break;
default:
break;
}
}
void ClangProjectSettingsWidget::customPchFileChanged()
{
ClangProjectSettings *cps = PchManager::instance()->settingsForProject(m_project);
Q_ASSERT(cps);
if (cps->pchUsage() != ClangProjectSettings::PchUse_Custom)
return;
QString fileName = m_ui.customField->text();
if (!QFile(fileName).exists())
return;
cps->setCustomPchFile(fileName);
}
void ClangProjectSettingsWidget::customPchButtonClicked()
{
ClangProjectSettings *cps = PchManager::instance()->settingsForProject(m_project);
Q_ASSERT(cps);
QFileDialog d(this);
d.setNameFilters(QStringList() << tr("Header Files (*.h)")
<< tr("All Files (*)"));
d.setFileMode(QFileDialog::ExistingFile);
d.setDirectory(m_project->projectDirectory().toString());
if (!d.exec())
return;
const QStringList fileNames = d.selectedFiles();
if (fileNames.isEmpty() || fileNames.first().isEmpty())
return;
m_ui.customField->setText(fileNames.first());
cps->setCustomPchFile(fileNames.first());
} }

View File

@@ -33,10 +33,8 @@
#include "ui_clangprojectsettingspropertiespage.h" #include "ui_clangprojectsettingspropertiespage.h"
#include <QString>
namespace ProjectExplorer { namespace ProjectExplorer {
class Project; class Project;
} }
namespace ClangCodeModel { namespace ClangCodeModel {
@@ -49,11 +47,6 @@ class ClangProjectSettingsWidget: public QWidget
public: public:
ClangProjectSettingsWidget(ProjectExplorer::Project *project); ClangProjectSettingsWidget(ProjectExplorer::Project *project);
protected slots:
void pchUsageChanged(int id);
void customPchFileChanged();
void customPchButtonClicked();
private: private:
Ui::ClangProjectSettingsPropertiesPage m_ui; Ui::ClangProjectSettingsPropertiesPage m_ui;
ProjectExplorer::Project *m_project; ProjectExplorer::Project *m_project;

View File

@@ -2,6 +2,9 @@
<ui version="4.0"> <ui version="4.0">
<class>ClangCodeModel::Internal::ClangProjectSettingsPropertiesPage</class> <class>ClangCodeModel::Internal::ClangProjectSettingsPropertiesPage</class>
<widget class="QWidget" name="ClangCodeModel::Internal::ClangProjectSettingsPropertiesPage"> <widget class="QWidget" name="ClangCodeModel::Internal::ClangProjectSettingsPropertiesPage">
<property name="enabled">
<bool>false</bool>
</property>
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>

View File

@@ -32,25 +32,18 @@
#include "clangeditordocumentprocessor.h" #include "clangeditordocumentprocessor.h"
#include <clang-c/Index.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <coreplugin/idocument.h> #include <coreplugin/idocument.h>
#include <cpptools/baseeditordocumentparser.h> #include <cpptools/baseeditordocumentparser.h>
#include <cpptools/cppprojects.h> #include <cpptools/cppprojects.h>
#include <cpptools/cppworkingcopy.h>
#include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/projectexplorerconstants.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <QDir> #include <QDir>
#include <QFile> #include <QFile>
#include <QLoggingCategory> #include <QLoggingCategory>
#include <QRegularExpression> #include <QRegularExpression>
#include <QSet> #include <QStringList>
#include <QString>
using namespace ClangCodeModel; using namespace ClangCodeModel;
using namespace ClangCodeModel::Internal; using namespace ClangCodeModel::Internal;
@@ -62,21 +55,6 @@ namespace Utils {
Q_LOGGING_CATEGORY(verboseRunLog, "qtc.clangcodemodel.verboserun") Q_LOGGING_CATEGORY(verboseRunLog, "qtc.clangcodemodel.verboserun")
UnsavedFiles createUnsavedFiles(const WorkingCopy &workingCopy,
const ::Utils::FileNameList &modifiedFiles)
{
UnsavedFiles result;
QHashIterator< ::Utils::FileName, QPair<QByteArray, unsigned> > wcIter = workingCopy.iterator();
while (wcIter.hasNext()) {
wcIter.next();
const ::Utils::FileName &fileName = wcIter.key();
if (modifiedFiles.contains(fileName) && QFile(fileName.toString()).exists())
result.insert(fileName.toString(), wcIter.value().first);
}
return result;
}
/** /**
* @brief Creates list of message-line arguments required for correct parsing * @brief Creates list of message-line arguments required for correct parsing
* @param pPart Null if file isn't part of any project * @param pPart Null if file isn't part of any project

View File

@@ -33,20 +33,15 @@
#include "clang_global.h" #include "clang_global.h"
#include <cpptools/cppmodelmanager.h> #include <cpptools/cppprojects.h>
#include <QLoggingCategory> #include <QLoggingCategory>
namespace ClangCodeModel { namespace ClangCodeModel {
namespace Utils { namespace Utils {
typedef QMap<QString, QByteArray> UnsavedFiles;
Q_DECLARE_LOGGING_CATEGORY(verboseRunLog) Q_DECLARE_LOGGING_CATEGORY(verboseRunLog)
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);
QStringList createClangOptions(const CppTools::ProjectPart::Ptr &pPart, QStringList createClangOptions(const CppTools::ProjectPart::Ptr &pPart,

View File

@@ -1,63 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** 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 The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "pchinfo.h"
#include <QDir>
using namespace ClangCodeModel::Internal;
PchInfo::PchInfo()
{
}
PchInfo::~PchInfo()
{
}
PchInfo::Ptr PchInfo::createEmpty()
{
return Ptr(new PchInfo);
}
PchInfo::Ptr PchInfo::createWithFileName(const QString &inputFileName,
const QStringList &options,
bool objcEnabled)
{
Ptr result(new PchInfo);
result->m_inputFileName = inputFileName;
result->m_options = options;
result->m_objcEnabled = objcEnabled;
// The next 2 lines are just here to generate the file name....
result->m_file.open();
result->m_file.close();
return result;
}

View File

@@ -1,81 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** 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 The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef PCHINFO_H
#define PCHINFO_H
#include <QString>
#include <QStringList>
#include <QSharedPointer>
#include <QTemporaryFile>
namespace ClangCodeModel {
namespace Internal {
class PchInfo
{
PchInfo();
public:
typedef QSharedPointer<PchInfo> Ptr;
public:
~PchInfo();
static Ptr createEmpty();
static Ptr createWithFileName(const QString &inputFileName,
const QStringList &options, bool objcEnabled);
/// \return the (temporary) file name for the PCH file.
QString fileName() const
{ return m_file.fileName(); }
/// \return the input file for the PCH compilation.
QString inputFileName() const
{ return m_inputFileName; }
/// \return the options used to generate this PCH file.
QStringList options() const
{ return m_options; }
bool objcWasEnabled() const
{ return m_objcEnabled; }
private:
QString m_inputFileName;
QStringList m_options;
bool m_objcEnabled;
QTemporaryFile m_file;
};
} // Internal namespace
} // ClangCodeModel namespace
#endif // PCHINFO_H

View File

@@ -1,512 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** 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 The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "pchmanager.h"
#include "unit.h"
#include "clangutils.h"
#include <coreplugin/icore.h>
#include <coreplugin/progressmanager/progressmanager.h>
#include <utils/qtcassert.h>
#include <utils/runextensions.h>
#include <QFile>
using namespace ClangCodeModel;
using namespace ClangCodeModel::Internal;
using namespace CPlusPlus;
namespace {
QString getQString(const CXString &cxString, bool disposeCXString = true)
{
QString s = QString::fromUtf8(clang_getCString(cxString));
if (disposeCXString)
clang_disposeString(cxString);
return s;
}
QStringList formattedDiagnostics(const Unit::Ptr &unit)
{
QStringList diags;
if (!unit->isLoaded())
return diags;
const unsigned count = unit->getNumDiagnostics();
for (unsigned i = 0; i < count; ++i) {
CXDiagnostic diag = unit->getDiagnostic(i);
unsigned opt = CXDiagnostic_DisplaySourceLocation
| CXDiagnostic_DisplayColumn
| CXDiagnostic_DisplaySourceRanges
| CXDiagnostic_DisplayOption
| CXDiagnostic_DisplayCategoryId
| CXDiagnostic_DisplayCategoryName
;
diags << getQString(clang_formatDiagnostic(diag, opt));
clang_disposeDiagnostic(diag);
}
return diags;
}
/**
* Utility method to create a PCH file from a header file.
*
* \returns a boolean indicating success (true) or failure (false), and a
* list of diagnostic messages.
*/
QPair<bool, QStringList> precompile(const PchInfo::Ptr &pchInfo)
{
// qDebug() << "*** Precompiling" << pchInfo->inputFileName()
// << "into" << pchInfo->fileName()
// << "with options" << pchInfo->options();
bool ok = false;
Unit::Ptr unit = Unit::create(pchInfo->inputFileName());
unit->setCompilationOptions(pchInfo->options());
unsigned parseOpts = CXTranslationUnit_ForSerialization
| CXTranslationUnit_Incomplete;
unit->setManagementOptions(parseOpts);
unit->parse();
if (unit->isLoaded())
ok = CXSaveError_None == unit->save(pchInfo->fileName());
return qMakePair(ok, formattedDiagnostics(unit));
}
} // anonymous namespace
PchManager *PchManager::m_instance = 0;
PchManager::PchManager(QObject *parent)
: QObject(parent)
{
Q_ASSERT(!m_instance);
m_instance = this;
QObject *msgMgr = Core::MessageManager::instance();
connect(this, SIGNAL(pchMessage(QString,Core::MessageManager::PrintToOutputPaneFlags)),
msgMgr, SLOT(write(QString,Core::MessageManager::PrintToOutputPaneFlags)));
connect(&m_pchGenerationWatcher, SIGNAL(finished()),
this, SLOT(updateActivePchFiles()));
}
PchManager::~PchManager()
{
Q_ASSERT(m_instance);
m_instance = 0;
qDeleteAll(m_projectSettings.values());
m_projectSettings.clear();
}
PchManager *PchManager::instance()
{
return m_instance;
}
PchInfo::Ptr PchManager::pchInfo(const ProjectPart::Ptr &projectPart) const
{
QMutexLocker locker(&m_mutex);
return m_activePchFiles[projectPart];
}
ClangProjectSettings *PchManager::settingsForProject(ProjectExplorer::Project *project)
{
QMutexLocker locker(&m_mutex);
ClangProjectSettings *cps = m_projectSettings.value(project);
if (!cps) {
cps = new ClangProjectSettings(project);
m_projectSettings.insert(project, cps);
cps->pullSettings();
connect(cps, SIGNAL(pchSettingsChanged()),
this, SLOT(clangProjectSettingsChanged()));
}
return cps;
}
void PchManager::setPCHInfo(const QList<ProjectPart::Ptr> &projectParts,
const PchInfo::Ptr &pchInfo,
const QPair<bool, QStringList> &msgs)
{
QMutexLocker locker(&m_mutex);
foreach (ProjectPart::Ptr pPart, projectParts)
m_activePchFiles[pPart] = pchInfo;
if (pchInfo) {
if (msgs.first) {
if (!pchInfo->fileName().isEmpty())
emit pchMessage(tr("Successfully generated PCH file \"%1\".").arg(
pchInfo->fileName()), Core::MessageManager::Silent);
} else {
emit pchMessage(tr("Failed to generate PCH file \"%1\".").arg(
pchInfo->fileName()), Core::MessageManager::Silent);
}
if (!msgs.second.isEmpty())
emit pchMessage(msgs.second.join(QLatin1Char('\n')), Core::MessageManager::Flash);
}
}
void PchManager::clangProjectSettingsChanged()
{
ClangProjectSettings *cps = qobject_cast<ClangProjectSettings *>(sender());
if (!cps)
return;
onProjectPartsUpdated(cps->project());
}
void PchManager::onAboutToRemoveProject(ProjectExplorer::Project *project)
{
Q_UNUSED(project);
// we cannot ask the ModelManager for the parts, because, depending on
// the order of signal delivery, it might already have wiped any information
// about the project.
updateActivePchFiles();
}
void PchManager::onProjectPartsUpdated(ProjectExplorer::Project *project)
{
ClangProjectSettings *cps = settingsForProject(project);
Q_ASSERT(cps);
CppTools::CppModelManager *mmi = CppTools::CppModelManager::instance();
const QList<ProjectPart::Ptr> projectParts = mmi->projectInfo(
cps->project()).projectParts();
updatePchInfo(cps, projectParts);
}
void PchManager::updatePchInfo(ClangProjectSettings *cps,
const QList<ProjectPart::Ptr> &projectParts)
{
if (m_pchGenerationWatcher.isRunning()) {
m_pchGenerationWatcher.waitForFinished();
}
const QString customPchFile = cps->customPchFile();
const ClangProjectSettings::PchUsage pchUsage = cps->pchUsage();
void (*updateFunction)(QFutureInterface<void> &future,
const PchManager::UpdateParams params) = 0;
QString message;
if (pchUsage == ClangProjectSettings::PchUse_None
|| (pchUsage == ClangProjectSettings::PchUse_Custom && customPchFile.isEmpty())) {
updateFunction = &PchManager::doPchInfoUpdateNone;
message = QLatin1String("updatePchInfo: switching to none");
} else if (pchUsage == ClangProjectSettings::PchUse_BuildSystem_Fuzzy) {
updateFunction = &PchManager::doPchInfoUpdateFuzzy;
message = QLatin1String("updatePchInfo: switching to build system (fuzzy)");
} else if (pchUsage == ClangProjectSettings::PchUse_BuildSystem_Exact) {
updateFunction = &PchManager::doPchInfoUpdateExact;
message = QLatin1String("updatePchInfo: switching to build system (exact)");
} else if (pchUsage == ClangProjectSettings::PchUse_Custom) {
updateFunction = &PchManager::doPchInfoUpdateCustom;
message = QLatin1String("updatePchInfo: switching to custom") + customPchFile;
}
QTC_ASSERT(updateFunction && !message.isEmpty(), return);
Core::MessageManager::write(message, Core::MessageManager::Silent);
QFuture<void> future = QtConcurrent::run(updateFunction,
UpdateParams(customPchFile, projectParts));
m_pchGenerationWatcher.setFuture(future);
Core::ProgressManager::addTask(future, tr("Precompiling"), "Key.Tmp.Precompiling");
}
namespace {
bool hasObjCFiles(const CppTools::ProjectPart::Ptr &projectPart)
{
foreach (const CppTools::ProjectFile &file, projectPart->files) {
switch (file.kind) {
case CppTools::ProjectFile::ObjCHeader:
case CppTools::ProjectFile::ObjCSource:
case CppTools::ProjectFile::ObjCXXHeader:
case CppTools::ProjectFile::ObjCXXSource:
return true;
default:
break;
}
}
return false;
}
bool hasCppFiles(const CppTools::ProjectPart::Ptr &projectPart)
{
foreach (const CppTools::ProjectFile &file, projectPart->files) {
switch (file.kind) {
case CppTools::ProjectFile::CudaSource:
case CppTools::ProjectFile::CXXHeader:
case CppTools::ProjectFile::CXXSource:
case CppTools::ProjectFile::OpenCLSource:
case CppTools::ProjectFile::ObjCXXHeader:
case CppTools::ProjectFile::ObjCXXSource:
return true;
default:
break;
}
}
return false;
}
CppTools::ProjectFile::Kind getPrefixFileKind(bool hasObjectiveC, bool hasCPlusPlus)
{
if (hasObjectiveC && hasCPlusPlus)
return CppTools::ProjectFile::ObjCXXHeader;
else if (hasObjectiveC)
return CppTools::ProjectFile::ObjCHeader;
else if (hasCPlusPlus)
return CppTools::ProjectFile::CXXHeader;
return CppTools::ProjectFile::CHeader;
}
}
void PchManager::doPchInfoUpdateNone(QFutureInterface<void> &future,
const PchManager::UpdateParams params)
{
future.setProgressRange(0, 1);
PchInfo::Ptr emptyPch = PchInfo::createEmpty();
PchManager::instance()->setPCHInfo(params.projectParts, emptyPch,
qMakePair(true, QStringList()));
future.setProgressValue(1);
}
void PchManager::doPchInfoUpdateFuzzy(QFutureInterface<void> &future,
const PchManager::UpdateParams params)
{
typedef ProjectPart::HeaderPath HeaderPath;
QHash<QString, QSet<HeaderPath>> headers;
QHash<QString, QSet<QByteArray> > definesPerPCH;
QHash<QString, bool> objc;
QHash<QString, bool> cplusplus;
QHash<QString, ProjectPart::QtVersion> qtVersions;
QHash<QString, ProjectPart::LanguageVersion> languageVersions;
QHash<QString, ProjectPart::LanguageExtensions> languageExtensionsMap;
QHash<QString, QList<ProjectPart::Ptr> > inputToParts;
foreach (const ProjectPart::Ptr &projectPart, params.projectParts) {
if (projectPart->precompiledHeaders.isEmpty())
continue;
const QString &pch = projectPart->precompiledHeaders.first(); // TODO: support more than 1 PCH file.
if (!QFile(pch).exists())
continue;
inputToParts[pch].append(projectPart);
headers[pch].unite(QSet<HeaderPath>::fromList(projectPart->headerPaths));
languageVersions[pch] = std::max(languageVersions.value(pch, ProjectPart::C89),
projectPart->languageVersion);
languageExtensionsMap[pch] = languageExtensionsMap[pch] | projectPart->languageExtensions;
if (hasObjCFiles(projectPart))
objc[pch] = true;
if (hasCppFiles(projectPart))
cplusplus[pch] = true;
QSet<QByteArray> projectDefines = QSet<QByteArray>::fromList(projectPart->toolchainDefines.split('\n'));
QMutableSetIterator<QByteArray> iter(projectDefines);
while (iter.hasNext()){
QByteArray v = iter.next();
if (v.startsWith("#define _") || v.isEmpty()) // TODO: see ProjectPart::createClangOptions
iter.remove();
}
projectDefines.unite(QSet<QByteArray>::fromList(projectPart->projectDefines.split('\n')));
if (definesPerPCH.contains(pch)) {
definesPerPCH[pch].intersect(projectDefines);
} else {
definesPerPCH[pch] = projectDefines;
}
qtVersions[pch] = projectPart->qtVersion;
}
future.setProgressRange(0, definesPerPCH.size() + 1);
future.setProgressValue(0);
foreach (const QString &pch, inputToParts.keys()) {
if (future.isCanceled())
return;
ProjectPart::Ptr projectPart(new ProjectPart);
projectPart->qtVersion = qtVersions[pch];
projectPart->languageVersion = languageVersions[pch];
projectPart->languageExtensions = languageExtensionsMap[pch];
projectPart->headerPaths = headers[pch].toList();
projectPart->updateLanguageFeatures();
QList<QByteArray> defines = definesPerPCH[pch].toList();
if (!defines.isEmpty()) {
projectPart->projectDefines = defines[0];
for (int i = 1; i < defines.size(); ++i) {
projectPart->projectDefines += '\n';
projectPart->projectDefines += defines[i];
}
}
CppTools::ProjectFile::Kind prefixFileKind =
getPrefixFileKind(objc.value(pch, false), cplusplus.value(pch, false));
QStringList options = Utils::createClangOptions(projectPart, prefixFileKind);
projectPart.clear();
PchManager *pchManager = PchManager::instance();
PchInfo::Ptr pchInfo = pchManager->findMatchingPCH(pch, options, true);
QPair<bool, QStringList> msgs = qMakePair(true, QStringList());
if (pchInfo.isNull()) {
pchInfo = PchInfo::createWithFileName(pch, options, objc[pch]);
msgs = precompile(pchInfo);
}
pchManager->setPCHInfo(inputToParts[pch], pchInfo, msgs);
future.setProgressValue(future.progressValue() + 1);
}
future.setProgressValue(future.progressValue() + 1);
}
void PchManager::doPchInfoUpdateExact(QFutureInterface<void> &future,
const PchManager::UpdateParams params)
{
future.setProgressRange(0, params.projectParts.size() + 1);
future.setProgressValue(0);
foreach (const ProjectPart::Ptr &projectPart, params.projectParts) {
if (future.isCanceled())
return;
if (projectPart->precompiledHeaders.isEmpty())
continue;
const QString &pch = projectPart->precompiledHeaders.first(); // TODO: support more than 1 PCH file.
if (!QFile(pch).exists())
continue;
const bool hasObjC = hasObjCFiles(projectPart);
QStringList options = Utils::createClangOptions(
projectPart, getPrefixFileKind(hasObjC, hasCppFiles(projectPart)));
PchManager *pchManager = PchManager::instance();
PchInfo::Ptr pchInfo = pchManager->findMatchingPCH(pch, options, false);
QPair<bool, QStringList> msgs = qMakePair(true, QStringList());
if (pchInfo.isNull()) {
pchInfo = PchInfo::createWithFileName(pch, options, hasObjC);
msgs = precompile(pchInfo);
}
pchManager->setPCHInfo(QList<ProjectPart::Ptr>() << projectPart,
pchInfo, msgs);
future.setProgressValue(future.progressValue() + 1);
}
future.setProgressValue(future.progressValue() + 1);
}
void PchManager::doPchInfoUpdateCustom(QFutureInterface<void> &future,
const PchManager::UpdateParams params)
{
future.setProgressRange(0, 1);
future.setProgressValue(0);
ProjectPart::HeaderPaths headers;
bool objc = false;
bool cplusplus = false;
ProjectPart::Ptr united(new ProjectPart());
united->languageVersion = ProjectPart::C89;
foreach (const ProjectPart::Ptr &projectPart, params.projectParts) {
headers += projectPart->headerPaths;
united->languageVersion = std::max(united->languageVersion, projectPart->languageVersion);
united->qtVersion = std::max(united->qtVersion, projectPart->qtVersion);
objc |= hasObjCFiles(projectPart);
cplusplus |= hasCppFiles(projectPart);
}
united->updateLanguageFeatures();
united->headerPaths = headers;
QStringList opts = Utils::createClangOptions(
united, getPrefixFileKind(objc, cplusplus));
united.clear();
PchManager *pchManager = PchManager::instance();
PchInfo::Ptr pchInfo = pchManager->findMatchingPCH(params.customPchFile, opts, true);
QPair<bool, QStringList> msgs = qMakePair(true, QStringList());;
if (future.isCanceled())
return;
if (pchInfo.isNull()) {
pchInfo = PchInfo::createWithFileName(params.customPchFile, opts, objc);
msgs = precompile(pchInfo);
}
pchManager->setPCHInfo(params.projectParts, pchInfo, msgs);
future.setProgressValue(1);
}
PchInfo::Ptr PchManager::findMatchingPCH(const QString &inputFileName,
const QStringList &options,
bool fuzzyMatching) const
{
QMutexLocker locker(&m_mutex);
if (fuzzyMatching) {
QStringList opts = options;
opts.sort();
foreach (PchInfo::Ptr pchInfo, m_activePchFiles.values()) {
if (pchInfo->inputFileName() != inputFileName)
continue;
QStringList pchOpts = pchInfo->options();
pchOpts.sort();
if (pchOpts == opts)
return pchInfo;
}
} else {
foreach (PchInfo::Ptr pchInfo, m_activePchFiles.values())
if (pchInfo->inputFileName() == inputFileName
&& pchInfo->options() == options)
return pchInfo;
}
return PchInfo::Ptr();
}
void PchManager::updateActivePchFiles()
{
QMutexLocker locker(&m_mutex);
QSet<ProjectPart::Ptr> activeParts;
CppTools::CppModelManager *mmi = CppTools::CppModelManager::instance();
foreach (const CppTools::ProjectInfo &pi, mmi->projectInfos())
activeParts.unite(QSet<ProjectPart::Ptr>::fromList(pi.projectParts()));
QList<ProjectPart::Ptr> partsWithPCHFiles = m_activePchFiles.keys();
foreach (ProjectPart::Ptr pPart, partsWithPCHFiles)
if (!activeParts.contains(pPart))
m_activePchFiles.remove(pPart);
}

View File

@@ -1,109 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** 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 The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef PCHMANAGER_H
#define PCHMANAGER_H
#include "clangprojectsettings.h"
#include "pchinfo.h"
#include <cpptools/cppmodelmanager.h>
#include <projectexplorer/project.h>
#include <coreplugin/messagemanager.h>
#include <QFutureWatcher>
#include <QHash>
#include <QMutex>
#include <QObject>
namespace ClangCodeModel {
namespace Internal {
class PchManager : public QObject
{
Q_OBJECT
typedef CppTools::ProjectPart ProjectPart;
static PchManager *m_instance;
public:
PchManager(QObject *parent = 0);
virtual ~PchManager();
static PchManager *instance();
PchInfo::Ptr pchInfo(const ProjectPart::Ptr &projectPart) const;
ClangProjectSettings *settingsForProject(ProjectExplorer::Project *project);
signals:
void pchMessage(const QString &message, Core::MessageManager::PrintToOutputPaneFlags flags);
public slots:
void clangProjectSettingsChanged();
void onAboutToRemoveProject(ProjectExplorer::Project *project);
void onProjectPartsUpdated(ProjectExplorer::Project *project);
private slots:
void updateActivePchFiles();
private:
struct UpdateParams {
UpdateParams(const QString &customPchFile, const QList<ProjectPart::Ptr> &projectParts)
: customPchFile(customPchFile) , projectParts(projectParts) {}
const QString customPchFile;
const QList<ProjectPart::Ptr> projectParts;
};
void updatePchInfo(ClangProjectSettings *cps,
const QList<ProjectPart::Ptr> &projectParts);
static void doPchInfoUpdateNone(QFutureInterface<void> &future, const UpdateParams params);
static void doPchInfoUpdateFuzzy(QFutureInterface<void> &future, const UpdateParams params);
static void doPchInfoUpdateExact(QFutureInterface<void> &future, const UpdateParams params);
static void doPchInfoUpdateCustom(QFutureInterface<void> &future, const UpdateParams params);
void setPCHInfo(const QList<ProjectPart::Ptr> &projectParts,
const PchInfo::Ptr &pchInfo,
const QPair<bool, QStringList> &msgs);
PchInfo::Ptr findMatchingPCH(const QString &inputFileName, const QStringList &options,
bool fuzzyMatching) const;
private:
mutable QMutex m_mutex;
QHash<ProjectPart::Ptr, PchInfo::Ptr> m_activePchFiles;
QHash<ProjectExplorer::Project *, ClangProjectSettings *> m_projectSettings;
QFutureWatcher<void> m_pchGenerationWatcher;
};
} // namespace Internal
} // namespace ClangCodeModel
#endif // PCHMANAGER_H

View File

@@ -1,104 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** 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 The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "scopedclangoptions.h"
namespace ClangCodeModel {
/**
* @class ClangCodeModel::ScopedClangOptions
* @brief Converts QStringList to raw options, acceptable by clang-c parsing and indexing API
*/
ScopedClangOptions::ScopedClangOptions(const QStringList &options)
: m_size(options.size())
, m_rawOptions(new const char*[options.size()])
{
for (int i = 0 ; i < m_size; ++i)
m_rawOptions[i] = qstrdup(options[i].toUtf8());
}
ScopedClangOptions::~ScopedClangOptions()
{
for (int i = 0; i < m_size; ++i)
delete[] m_rawOptions[i];
delete[] m_rawOptions;
}
const char **ScopedClangOptions::data() const
{
return m_rawOptions;
}
int ScopedClangOptions::size() const
{
return m_size;
}
/**
* @class ClangCodeModel::SharedClangOptions
* @brief Shared wrapper around \a {ClangCodeModel::ScopedClangOptions} ScopedClangOptions
*/
SharedClangOptions::SharedClangOptions()
: d(0)
{
}
SharedClangOptions::SharedClangOptions(const QStringList &options)
: d(new ScopedClangOptions(options))
{
}
/**
* @return Replaces options with new options list
*/
void SharedClangOptions::reloadOptions(const QStringList &options)
{
d = QSharedPointer<ScopedClangOptions>(new ScopedClangOptions(options));
}
/**
* @return Pointer to clang raw options or NULL if uninitialized
*/
const char **SharedClangOptions::data() const
{
return d ? d->data() : 0;
}
/**
* @return Options count or 0 if uninitialized
*/
int SharedClangOptions::size() const
{
return d ? d->size() : 0;
}
} // namespace ClangCodeModel

View File

@@ -1,73 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** 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 The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef CLANGCODEMODEL_SCOPEDCLANGOPTIONS_H
#define CLANGCODEMODEL_SCOPEDCLANGOPTIONS_H
#include "../clang_global.h"
#include <QStringList>
#include <QSharedPointer>
namespace ClangCodeModel {
class CLANG_EXPORT ScopedClangOptions
{
public:
ScopedClangOptions(const QStringList &options);
~ScopedClangOptions();
const char **data() const;
int size() const;
private:
void release();
int m_size;
const char **m_rawOptions;
};
class CLANG_EXPORT SharedClangOptions
{
public:
SharedClangOptions();
SharedClangOptions(const QStringList &options);
void reloadOptions(const QStringList &options);
const char **data() const;
int size() const;
private:
QSharedPointer<ScopedClangOptions> d;
};
} // namespace ClangCodeModel
#endif // CLANGCODEMODEL_SCOPEDCLANGOPTIONS_H

View File

@@ -1,335 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** 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 The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "unit.h"
#include "clangutils.h"
#include "unsavedfiledata.h"
#include <clang-c/Index.h>
#include <QtCore/QByteArray>
#include <QtCore/QVector>
#include <QtCore/QSharedData>
#ifdef DEBUG_UNIT_COUNT
# include <QAtomicInt>
# include <QDebug>
static QBasicAtomicInt unitDataCount = Q_BASIC_ATOMIC_INITIALIZER(0);
#endif // DEBUG_UNIT_COUNT
using namespace ClangCodeModel;
using namespace ClangCodeModel::Internal;
Unit::Unit()
: m_index(0)
, m_tu(0)
, m_managementOptions(0)
{}
Unit::Unit(const QString &fileName)
: m_index(clang_createIndex(/*excludeDeclsFromPCH*/ 1, Utils::verboseRunLog().isDebugEnabled()))
, m_tu(0)
, m_fileName(fileName.toUtf8())
, m_managementOptions(0)
{}
Unit::~Unit()
{
unload();
clang_disposeIndex(m_index);
m_index = 0;
}
Unit::Ptr Unit::create()
{
return Unit::Ptr(new Unit);
}
Unit::Ptr Unit::create(const QString &fileName)
{
return Unit::Ptr(new Unit(fileName));
}
const QString Unit::fileName() const
{
return QString::fromUtf8(m_fileName.data(), m_fileName.size());
}
bool Unit::isLoaded() const
{
return m_tu && m_index;
}
const QDateTime &Unit::timeStamp() const
{
return m_timeStamp;
}
QStringList Unit::compilationOptions() const
{
return m_compOptions;
}
void Unit::setCompilationOptions(const QStringList &compOptions)
{
m_compOptions = compOptions;
m_sharedCompOptions.reloadOptions(compOptions);
}
ClangCodeModel::Utils::UnsavedFiles Unit::unsavedFiles() const
{
return m_unsaved;
}
void Unit::setUnsavedFiles(const ClangCodeModel::Utils::UnsavedFiles &unsavedFiles)
{
m_unsaved = unsavedFiles;
}
unsigned Unit::managementOptions() const
{
return m_managementOptions;
}
void Unit::setManagementOptions(unsigned managementOptions)
{
m_managementOptions = managementOptions;
}
void Unit::parse()
{
unload();
updateTimeStamp();
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_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_tu, unitFileName.toUtf8().constData(),
clang_defaultSaveOptions(m_tu));
}
void Unit::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_tu, m_fileName.constData());
}
CXCursor Unit::getCursor(const CXSourceLocation &location) const
{
Q_ASSERT(isLoaded());
return clang_getCursor(m_tu, location);
}
CXSourceLocation Unit::getLocation(const CXFile &file, unsigned line, unsigned column) const
{
Q_ASSERT(isLoaded());
return clang_getLocation(m_tu, file, line, column);
}
void Unit::tokenize(CXSourceRange range, CXToken **tokens, unsigned *tokenCount) const
{
Q_ASSERT(isLoaded());
Q_ASSERT(tokens);
Q_ASSERT(tokenCount);
Q_ASSERT(!clang_Range_isNull(range));
clang_tokenize(m_tu, range, tokens, tokenCount);
}
void Unit::disposeTokens(CXToken *tokens, unsigned tokenCount) const
{
Q_ASSERT(isLoaded());
clang_disposeTokens(m_tu, tokens, tokenCount);
}
CXSourceRange Unit::getTokenExtent(const CXToken &token) const
{
Q_ASSERT(isLoaded());
return clang_getTokenExtent(m_tu, token);
}
void Unit::annotateTokens(CXToken *tokens, unsigned tokenCount, CXCursor *cursors) const
{
Q_ASSERT(isLoaded());
Q_ASSERT(tokens);
Q_ASSERT(cursors);
clang_annotateTokens(m_tu, tokens, tokenCount, cursors);
}
CXTranslationUnit Unit::clangTranslationUnit() const
{
Q_ASSERT(isLoaded());
return m_tu;
}
CXIndex Unit::clangIndex() const
{
Q_ASSERT(isLoaded());
return m_index;
}
CXCursor Unit::getTranslationUnitCursor() const
{
Q_ASSERT(isLoaded());
return clang_getTranslationUnitCursor(m_tu);
}
CXString Unit::getTranslationUnitSpelling() const
{
Q_ASSERT(isLoaded());
return clang_getTranslationUnitSpelling(m_tu);
}
void Unit::getInclusions(CXInclusionVisitor visitor, CXClientData clientData) const
{
Q_ASSERT(isLoaded());
clang_getInclusions(m_tu, visitor, clientData);
}
unsigned Unit::getNumDiagnostics() const
{
Q_ASSERT(isLoaded());
return clang_getNumDiagnostics(m_tu);
}
CXDiagnostic Unit::getDiagnostic(unsigned index) const
{
Q_ASSERT(isLoaded());
return clang_getDiagnostic(m_tu, index);
}
void Unit::updateTimeStamp()
{
m_timeStamp = QDateTime::currentDateTime();
}
IdentifierTokens::IdentifierTokens(const Unit &unit, unsigned firstLine, unsigned lastLine)
: m_unit(unit)
, m_tokenCount(0)
, m_tokens(0)
, m_cursors(0)
, m_extents(0)
{
Q_ASSERT(unit.isLoaded());
// Calculate the range:
CXFile file = unit.getFile();
CXSourceLocation startLocation = unit.getLocation(file, firstLine, 1);
CXSourceLocation endLocation = unit.getLocation(file, lastLine, 1);
CXSourceRange range = clang_getRange(startLocation, endLocation);
// Retrieve all identifier tokens:
unit.tokenize(range, &m_tokens, &m_tokenCount);
if (m_tokenCount == 0)
return;
// Get the cursors for the tokens:
m_cursors = new CXCursor[m_tokenCount];
unit.annotateTokens(m_tokens,
m_tokenCount,
m_cursors);
m_extents = new CXSourceRange[m_tokenCount];
// Create the markers using the cursor to check the types:
for (unsigned i = 0; i < m_tokenCount; ++i)
m_extents[i] = unit.getTokenExtent(m_tokens[i]);
}
IdentifierTokens::~IdentifierTokens()
{
dispose();
}
void IdentifierTokens::dispose()
{
if (!m_unit.isLoaded())
return;
if (m_tokenCount && m_tokens) {
m_unit.disposeTokens(m_tokens, m_tokenCount);
m_tokens = 0;
m_tokenCount = 0;
}
if (m_cursors) {
delete[] m_cursors;
m_cursors = 0;
}
if (m_extents) {
delete[] m_extents;
m_extents = 0;
}
}

View File

@@ -1,197 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** 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 The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef UNIT_H
#define UNIT_H
#include "clangutils.h"
#include "raii/scopedclangoptions.h"
#include <clang-c/Index.h>
#include <QtCore/QDateTime>
#include <QSharedPointer>
#include <QMetaType>
#include <QString>
#include <QStringList>
#include <QVarLengthArray>
QT_BEGIN_NAMESPACE
class QDateTime;
QT_END_NAMESPACE
namespace ClangCodeModel {
namespace Internal {
class UnitData;
/*
* This is a minimal wrapper around clang's translation unit functionality.
* It should should contain only the very basic primitives which allow other
* components such as code completion, code navigation, and others to access
* data which directly depends on the translation unit.
*
* In other words, what's wrapped here is only the functions that receive a
* CXTranslationUnit as a parameter. And this class itself is then the corresponding
* abstraction of the CXTranslationUnit.
*
* Notes:
* - 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.
*
* @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
* an underlying component and aslo don't provide the data in a fine granularity as
* needed here. At some point we should split ClangWrapper into its different logical
* components and use this is the underlying structure.
*/
class Unit
{
Q_DISABLE_COPY(Unit)
Unit();
explicit Unit(const QString &fileName);
public:
~Unit();
typedef QSharedPointer<Unit> Ptr;
static Ptr create();
static Ptr create(const QString &fileName);
bool isLoaded() const;
const QString fileName() const;
const QDateTime &timeStamp() const;
QStringList compilationOptions() const;
void setCompilationOptions(const QStringList &compOptions);
Utils::UnsavedFiles unsavedFiles() const;
void setUnsavedFiles(const ClangCodeModel::Utils::UnsavedFiles &unsavedFiles);
unsigned managementOptions() const;
void setManagementOptions(unsigned managementOptions);
// 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();
int save(const QString &unitFileName);
void unload();
// Simple forwarding methods, separated by clang categories for convenience.
// As above, the names are directly mapped. Separated by categories as clang for convenience.
// Note that only methods that take the TU as a parameter should be wrapped.
// - Diagnostic reporting
unsigned getNumDiagnostics() const;
CXDiagnostic getDiagnostic(unsigned index) const;
// - Translation unit manipulation
CXString getTranslationUnitSpelling() const;
// - File manipulation routines
CXFile getFile() const;
// - Mapping between cursors and source code
CXCursor getCursor(const CXSourceLocation &location) const;
// - Miscellaneous utility functions
void getInclusions(CXInclusionVisitor visitor, CXClientData clientData) const;
// - Cursor manipulations
CXCursor getTranslationUnitCursor() const;
// - Physical source locations
CXSourceLocation getLocation(const CXFile &file, unsigned line, unsigned column) const;
void tokenize(CXSourceRange range, CXToken **tokens, unsigned *tokenCount) const;
void disposeTokens(CXToken *tokens, unsigned tokenCount) const;
CXSourceRange getTokenExtent(const CXToken &token) const;
void annotateTokens(CXToken *tokens, unsigned tokenCount, CXCursor *cursors) const;
CXTranslationUnit clangTranslationUnit() const;
CXIndex clangIndex() const;
private:
void updateTimeStamp();
CXIndex m_index;
CXTranslationUnit m_tu;
QByteArray m_fileName;
QStringList m_compOptions;
SharedClangOptions m_sharedCompOptions;
unsigned m_managementOptions;
Utils::UnsavedFiles m_unsaved;
QDateTime m_timeStamp;
};
class IdentifierTokens
{
Q_DISABLE_COPY(IdentifierTokens)
public:
IdentifierTokens(const Unit &m_unit, unsigned firstLine, unsigned lastLine);
~IdentifierTokens();
unsigned count() const
{ return m_tokenCount; }
const CXToken &token(unsigned nr) const
{ Q_ASSERT(nr < count()); return m_tokens[nr]; }
const CXCursor &cursor(unsigned nr) const
{ Q_ASSERT(nr < count()); return m_cursors[nr]; }
const CXSourceRange &extent(unsigned nr) const
{ Q_ASSERT(nr < count()); return m_extents[nr]; }
private:
void dispose();
private:
const Unit &m_unit;
unsigned m_tokenCount;
CXToken *m_tokens;
CXCursor *m_cursors;
CXSourceRange *m_extents;
};
} // Internal
} // Clang
Q_DECLARE_METATYPE(ClangCodeModel::Internal::Unit::Ptr)
#endif // UNIT_H

View File

@@ -1,62 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** 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 The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "unsavedfiledata.h"
using namespace ClangCodeModel::Internal;
UnsavedFileData::UnsavedFileData(const UnsavedFiles &unsavedFiles)
: m_count(unsavedFiles.count())
, m_files(0)
{
if (m_count) {
m_files = new CXUnsavedFile[m_count];
unsigned idx = 0;
for (UnsavedFiles::const_iterator it = unsavedFiles.begin(); it != unsavedFiles.end(); ++it, ++idx) {
QByteArray contents = it.value();
const char *contentChars = qstrdup(contents.constData());
m_files[idx].Contents = contentChars;
m_files[idx].Length = contents.size();
const char *fileName = qstrdup(it.key().toUtf8().constData());
m_files[idx].Filename = fileName;
}
}
}
UnsavedFileData::~UnsavedFileData()
{
for (unsigned i = 0; i < m_count; ++i) {
delete[] m_files[i].Contents;
delete[] m_files[i].Filename;
}
delete[] m_files;
}

View File

@@ -1,66 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** 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 The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef CLANG_INTERNAL_UNSAVEDFILEDATA_H
#define CLANG_INTERNAL_UNSAVEDFILEDATA_H
#include "clangutils.h"
#include <clang-c/Index.h>
namespace ClangCodeModel {
namespace Internal {
class UnsavedFileData
{
UnsavedFileData(const UnsavedFileData &);
UnsavedFileData &operator=(const UnsavedFileData &);
typedef ClangCodeModel::Utils::UnsavedFiles UnsavedFiles;
public:
UnsavedFileData(const UnsavedFiles &unsavedFiles);
~UnsavedFileData();
unsigned count() const
{ return m_count; }
CXUnsavedFile *files() const
{ return m_files; }
private:
unsigned m_count;
CXUnsavedFile *m_files;
};
} // namespace Internal
} // namespace ClangCodeModel
#endif // CLANG_INTERNAL_UNSAVEDFILEDATA_H