From 507452f0971105e772e2c4913720cdd136ed2ca9 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Mon, 30 Sep 2013 13:36:01 +0200 Subject: [PATCH] CppTools: honor pre-compiled headers in the code-model. Task-number: QTCREATORBUG-476 Change-Id: I82ed92acdcda551d2c6a9ca221832ac20117a08f Reviewed-by: Nikolai Kosjar --- src/plugins/cpptools/cppcodemodelsettings.cpp | 3 + src/plugins/cpptools/cppcodemodelsettings.h | 19 +++- .../cpptools/cppcodemodelsettingspage.cpp | 16 ++- .../cpptools/cppcodemodelsettingspage.ui | 21 +++- src/plugins/cpptools/cppmodelmanager_test.cpp | 100 ++++++++++++++++++ src/plugins/cpptools/cppsnapshotupdater.cpp | 19 ++++ src/plugins/cpptools/cppsnapshotupdater.h | 4 + src/plugins/cpptools/cpptoolsconstants.h | 1 + .../cpptools/cpptoolseditorsupport.cpp | 5 + src/plugins/cpptools/cpptoolsplugin.cpp | 2 +- src/plugins/cpptools/cpptoolsplugin.h | 1 + tests/cppmodelmanager/testdata_defines/pch1.h | 1 + tests/cppmodelmanager/testdata_defines/pch2.h | 1 + 13 files changed, 187 insertions(+), 6 deletions(-) create mode 100644 tests/cppmodelmanager/testdata_defines/pch1.h create mode 100644 tests/cppmodelmanager/testdata_defines/pch2.h diff --git a/src/plugins/cpptools/cppcodemodelsettings.cpp b/src/plugins/cpptools/cppcodemodelsettings.cpp index a115d16bd0e..d319f5c5dbe 100644 --- a/src/plugins/cpptools/cppcodemodelsettings.cpp +++ b/src/plugins/cpptools/cppcodemodelsettings.cpp @@ -42,6 +42,8 @@ void CppCodeModelSettings::fromSettings(QSettings *s) setIdForMimeType(supporters, QLatin1String(Constants::CPP_SOURCE_MIMETYPE)); setIdForMimeType(supporters, QLatin1String(Constants::OBJECTIVE_C_SOURCE_MIMETYPE)); setIdForMimeType(supporters, QLatin1String(Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE)); + QVariant v = s->value(QLatin1String(Constants::CPPTOOLS_MODEL_MANAGER_PCH_USAGE), PchUse_None); + setPCHUsage(static_cast(v.toInt())); s->endGroup(); } @@ -52,6 +54,7 @@ void CppCodeModelSettings::toSettings(QSettings *s) foreach (const QString &mimeType, m_modelManagerSupportByMimeType.keys()) var[mimeType] = m_modelManagerSupportByMimeType[mimeType]; s->setValue(QLatin1String(Constants::CPPTOOLS_MODEL_MANAGER_SUPPORTERS_KEY), QVariant(var)); + s->setValue(QLatin1String(Constants::CPPTOOLS_MODEL_MANAGER_PCH_USAGE), pchUsage()); s->endGroup(); } diff --git a/src/plugins/cpptools/cppcodemodelsettings.h b/src/plugins/cpptools/cppcodemodelsettings.h index be4042a318d..ef1f8d63e09 100644 --- a/src/plugins/cpptools/cppcodemodelsettings.h +++ b/src/plugins/cpptools/cppcodemodelsettings.h @@ -43,11 +43,15 @@ namespace Internal { class CppCodeModelSettings { - QHash m_modelManagerSupportByMimeType; - QHash m_availableModelManagerSupportersByName; - QString m_defaultId; +public: + enum PCHUsage { + PchUse_None = 1, + PchUse_BuildSystem = 2, + }; public: + CppCodeModelSettings(): m_pchUsage(PchUse_None) {} + void fromSettings(QSettings *s); void toSettings(QSettings *s); @@ -65,8 +69,17 @@ public: void setDefaultId(const QString &defaultId) { m_defaultId = defaultId; } + PCHUsage pchUsage() const { return m_pchUsage; } + void setPCHUsage(PCHUsage pchUsage) { m_pchUsage = pchUsage; } + private: void setIdForMimeType(const QVariant &var, const QString &mimeType); + +private: + QHash m_modelManagerSupportByMimeType; + QHash m_availableModelManagerSupportersByName; + QString m_defaultId; + PCHUsage m_pchUsage; }; } // namespace Internal diff --git a/src/plugins/cpptools/cppcodemodelsettingspage.cpp b/src/plugins/cpptools/cppcodemodelsettingspage.cpp index af18b70445d..e5fd37824a6 100644 --- a/src/plugins/cpptools/cppcodemodelsettingspage.cpp +++ b/src/plugins/cpptools/cppcodemodelsettingspage.cpp @@ -43,6 +43,8 @@ CppCodeModelSettingsWidget::CppCodeModelSettingsWidget(QWidget *parent) , m_ui(new Ui::CppCodeModelSettingsPage) { m_ui->setupUi(this); + + m_ui->theGroupBox->setVisible(false); } CppCodeModelSettingsWidget::~CppCodeModelSettingsWidget() @@ -58,6 +60,8 @@ void CppCodeModelSettingsWidget::setSettings(const QSharedPointercppChooser, QLatin1String(Constants::CPP_SOURCE_MIMETYPE)); applyToWidget(m_ui->objcChooser, QLatin1String(Constants::OBJECTIVE_C_SOURCE_MIMETYPE)); applyToWidget(m_ui->objcppChooser, QLatin1String(Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE)); + + m_ui->ignorePCHCheckBox->setChecked(s->pchUsage() == CppCodeModelSettings::PchUse_None); } void CppCodeModelSettingsWidget::applyToWidget(QComboBox *chooser, const QString &mimeType) const @@ -85,6 +89,14 @@ void CppCodeModelSettingsWidget::applyToSettings() const changed |= applyToSettings(m_ui->objcppChooser, QLatin1String(Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE)); + if (m_ui->ignorePCHCheckBox->isChecked() != + (m_settings->pchUsage() == CppCodeModelSettings::PchUse_None)) { + m_settings->setPCHUsage( + m_ui->ignorePCHCheckBox->isChecked() ? CppCodeModelSettings::PchUse_None + : CppCodeModelSettings::PchUse_BuildSystem); + changed = true; + } + if (changed) m_settings->toSettings(Core::ICore::settings()); } @@ -97,7 +109,9 @@ QString CppCodeModelSettingsWidget::searchKeywords() const << ' ' << m_ui->cLabel->text() << ' ' << m_ui->cppLabel->text() << ' ' << m_ui->objcLabel->text() - << ' ' << m_ui->objcppLabel->text(); + << ' ' << m_ui->objcppLabel->text() + << ' ' << m_ui->anotherGroupBox->title() + << ' ' << m_ui->ignorePCHCheckBox->text(); foreach (const QString &mmsNames, m_settings->availableModelManagerSupportersByName().keys()) ts << ' ' << mmsNames; rc.remove(QLatin1Char('&')); diff --git a/src/plugins/cpptools/cppcodemodelsettingspage.ui b/src/plugins/cpptools/cppcodemodelsettingspage.ui index 70155c527b9..310c01d966e 100644 --- a/src/plugins/cpptools/cppcodemodelsettingspage.ui +++ b/src/plugins/cpptools/cppcodemodelsettingspage.ui @@ -13,7 +13,7 @@ Form - + @@ -77,6 +77,25 @@ + + + + Pre-compiled Headers + + + + + + <html><head/><body><p>When pre-compiled headers are not ignored, the parsing for code completion and semantic highlighting will process the pre-compiled header before processing any file.</p></body></html> + + + Ignore pre-compiled headers + + + + + + diff --git a/src/plugins/cpptools/cppmodelmanager_test.cpp b/src/plugins/cpptools/cppmodelmanager_test.cpp index 17391483e0c..db76d6ecc12 100644 --- a/src/plugins/cpptools/cppmodelmanager_test.cpp +++ b/src/plugins/cpptools/cppmodelmanager_test.cpp @@ -870,3 +870,103 @@ void CppToolsPlugin::test_modelmanager_defines_per_project() QCOMPARE(decl->name()->identifier()->chars(), "two"); } } + +void CppToolsPlugin::test_modelmanager_defines_per_project_pch() +{ + ModelManagerTestHelper helper; + + MyTestDataDir testDataDirectory(QLatin1String("testdata_defines")); + const QString main1File = testDataDirectory.file(QLatin1String("main1.cpp")); + const QString main2File = testDataDirectory.file(QLatin1String("main2.cpp")); + const QString header = testDataDirectory.file(QLatin1String("header.h")); + const QString pch1File = testDataDirectory.file(QLatin1String("pch1.h")); + const QString pch2File = testDataDirectory.file(QLatin1String("pch2.h")); + + CppModelManager *mm = CppModelManager::instance(); + + Project *project = helper.createProject( + QLatin1String("test_modelmanager_defines_per_project_pch")); + + ProjectPart::Ptr part1(new ProjectPart); + part1->files.append(ProjectFile(main1File, ProjectFile::CXXSource)); + part1->files.append(ProjectFile(header, ProjectFile::CXXHeader)); + part1->cxxVersion = ProjectPart::CXX11; + part1->qtVersion = ProjectPart::NoQt; + part1->precompiledHeaders.append(pch1File); + part1->includePaths = QStringList() << testDataDirectory.includeDir(false); + + ProjectPart::Ptr part2(new ProjectPart); + part2->files.append(ProjectFile(main2File, ProjectFile::CXXSource)); + part2->files.append(ProjectFile(header, ProjectFile::CXXHeader)); + part2->cxxVersion = ProjectPart::CXX11; + part2->qtVersion = ProjectPart::NoQt; + part2->precompiledHeaders.append(pch2File); + part2->includePaths = QStringList() << testDataDirectory.includeDir(false); + + ProjectInfo pi = mm->projectInfo(project); + pi.appendProjectPart(part1); + pi.appendProjectPart(part2); + + mm->updateProjectInfo(pi); + + helper.waitForRefreshedSourceFiles(); + + QCOMPARE(mm->snapshot().size(), 4); + + // Open a file in the editor + QCOMPARE(Core::EditorManager::documentModel()->openedDocuments().size(), 0); + + { + Core::IEditor *editor = Core::EditorManager::openEditor(main1File); + EditorCloser closer(editor); + QVERIFY(editor); + QCOMPARE(Core::EditorManager::documentModel()->openedDocuments().size(), 1); + QVERIFY(mm->isCppEditor(editor)); + + CppEditorSupport *sup = mm->cppEditorSupport( + qobject_cast(editor)); + while (sup->lastSemanticInfoDocument().isNull()) + QCoreApplication::processEvents(); + + sup->snapshotUpdater()->setUsePrecompiledHeaders(true); + sup->snapshotUpdater()->update(mm->workingCopy()); + + Document::Ptr doc = mm->snapshot().document(main1File); + QVERIFY(doc); + QVERIFY(doc->globalNamespace()); + QCOMPARE(doc->globalSymbolCount(), 1U); + CPlusPlus::Symbol *s = doc->globalSymbolAt(0); + QVERIFY(s); + CPlusPlus::Declaration *decl = s->asDeclaration(); + QVERIFY(decl); + QVERIFY(decl->type()->isIntegerType()); + QCOMPARE(decl->name()->identifier()->chars(), "one"); + } + + { + Core::IEditor *editor = Core::EditorManager::openEditor(main2File); + EditorCloser closer(editor); + QVERIFY(editor); + QCOMPARE(Core::EditorManager::documentModel()->openedDocuments().size(), 1); + QVERIFY(mm->isCppEditor(editor)); + + CppEditorSupport *sup = mm->cppEditorSupport( + qobject_cast(editor)); + while (sup->lastSemanticInfoDocument().isNull()) + QCoreApplication::processEvents(); + + sup->snapshotUpdater()->setUsePrecompiledHeaders(true); + sup->snapshotUpdater()->update(mm->workingCopy()); + + Document::Ptr doc = mm->snapshot().document(main2File); + QVERIFY(doc); + QVERIFY(doc->globalNamespace()); + QCOMPARE(doc->globalSymbolCount(), 1U); + CPlusPlus::Symbol *s = doc->globalSymbolAt(0); + QVERIFY(s); + CPlusPlus::Declaration *decl = s->asDeclaration(); + QVERIFY(decl); + QVERIFY(decl->type()->isIntegerType()); + QCOMPARE(decl->name()->identifier()->chars(), "two"); + } +} diff --git a/src/plugins/cpptools/cppsnapshotupdater.cpp b/src/plugins/cpptools/cppsnapshotupdater.cpp index f12f888af78..473ec66b607 100644 --- a/src/plugins/cpptools/cppsnapshotupdater.cpp +++ b/src/plugins/cpptools/cppsnapshotupdater.cpp @@ -39,6 +39,7 @@ using namespace CppTools::Internal; SnapshotUpdater::SnapshotUpdater(const QString &fileInEditor) : m_mutex(QMutex::Recursive) , m_fileInEditor(fileInEditor) + , m_usePrecompiledHeaders(false) { } @@ -56,6 +57,7 @@ void SnapshotUpdater::update(CppModelManager::WorkingCopy workingCopy) QByteArray configFile = modelManager->codeModelConfiguration(); QStringList includePaths; QStringList frameworkPaths; + QStringList precompiledHeaders; updateProjectPart(); @@ -63,6 +65,8 @@ void SnapshotUpdater::update(CppModelManager::WorkingCopy workingCopy) configFile += m_projectPart->defines; includePaths = m_projectPart->includePaths; frameworkPaths = m_projectPart->frameworkPaths; + if (m_usePrecompiledHeaders) + precompiledHeaders = m_projectPart->precompiledHeaders; } if (configFile != m_configFile) { @@ -81,6 +85,11 @@ void SnapshotUpdater::update(CppModelManager::WorkingCopy workingCopy) invalidateSnapshot = true; } + if (precompiledHeaders != m_precompiledHeaders) { + m_precompiledHeaders = precompiledHeaders; + invalidateSnapshot = true; + } + unsigned rev = 0; if (Document::Ptr doc = document()) rev = doc->revision(); @@ -130,6 +139,9 @@ void SnapshotUpdater::update(CppModelManager::WorkingCopy workingCopy) preproc.setIncludePaths(m_includePaths); preproc.setFrameworkPaths(m_frameworkPaths); preproc.run(configurationFileName); + if (m_usePrecompiledHeaders) + foreach (const QString &precompiledHeader, m_precompiledHeaders) + preproc.run(precompiledHeader); preproc.run(m_fileInEditor); m_snapshot = preproc.snapshot(); @@ -159,6 +171,13 @@ Document::Ptr SnapshotUpdater::document() const return m_snapshot.document(m_fileInEditor); } +void SnapshotUpdater::setUsePrecompiledHeaders(bool usePrecompiledHeaders) +{ + QMutexLocker locker(&m_mutex); + + m_usePrecompiledHeaders = usePrecompiledHeaders; +} + void SnapshotUpdater::updateProjectPart() { CppModelManager *cmm = dynamic_cast(CppModelManagerInterface::instance()); diff --git a/src/plugins/cpptools/cppsnapshotupdater.h b/src/plugins/cpptools/cppsnapshotupdater.h index 8db54def7e1..6f0f90ac4f9 100644 --- a/src/plugins/cpptools/cppsnapshotupdater.h +++ b/src/plugins/cpptools/cppsnapshotupdater.h @@ -64,6 +64,8 @@ public: QStringList frameworkPaths() const { return m_frameworkPaths; } + void setUsePrecompiledHeaders(bool usePrecompiledHeaders); + private: void updateProjectPart(); void addFileAndDependencies(QSet *toRemove, const QString &fileName) const; @@ -75,8 +77,10 @@ private: QByteArray m_configFile; QStringList m_includePaths; QStringList m_frameworkPaths; + QStringList m_precompiledHeaders; CPlusPlus::Snapshot m_snapshot; CPlusPlus::DependencyTable m_deps; + bool m_usePrecompiledHeaders; }; } // namespace CppTools diff --git a/src/plugins/cpptools/cpptoolsconstants.h b/src/plugins/cpptools/cpptoolsconstants.h index 0fa5d036cd6..ae3d384f2fb 100644 --- a/src/plugins/cpptools/cpptoolsconstants.h +++ b/src/plugins/cpptools/cpptoolsconstants.h @@ -52,6 +52,7 @@ const char CPPTOOLS_SETTINGSGROUP[] = "CppTools"; const char LOWERCASE_CPPFILES_KEY[] = "LowerCaseFiles"; enum { lowerCaseFilesDefault = 1 }; const char CPPTOOLS_MODEL_MANAGER_SUPPORTERS_KEY[] = "ModelManagerSupporters"; +const char CPPTOOLS_MODEL_MANAGER_PCH_USAGE[] = "PCHUsage"; const char CPP_CODE_STYLE_SETTINGS_ID[] = "A.Code Style"; const char CPP_CODE_STYLE_SETTINGS_NAME[] = QT_TRANSLATE_NOOP("CppTools", "Code Style"); diff --git a/src/plugins/cpptools/cpptoolseditorsupport.cpp b/src/plugins/cpptools/cpptoolseditorsupport.cpp index 98e913deddd..c1053c22181 100644 --- a/src/plugins/cpptools/cpptoolseditorsupport.cpp +++ b/src/plugins/cpptools/cpptoolseditorsupport.cpp @@ -27,8 +27,10 @@ ** ****************************************************************************/ +#include "cppcodemodelsettings.h" #include "cppcompletionassistprovider.h" #include "cpptoolseditorsupport.h" +#include "cpptoolsplugin.h" #include "cppmodelmanager.h" #include "cpplocalsymbols.h" @@ -251,6 +253,9 @@ QSharedPointer CppEditorSupport::snapshotUpdater() if (!updater) { updater = QSharedPointer(new SnapshotUpdater(fileName())); m_snapshotUpdater = updater; + + QSharedPointer cms = CppToolsPlugin::instance()->codeModelSettings(); + updater->setUsePrecompiledHeaders(cms->pchUsage() != CppCodeModelSettings::PchUse_None); } return updater; } diff --git a/src/plugins/cpptools/cpptoolsplugin.cpp b/src/plugins/cpptools/cpptoolsplugin.cpp index 3d84020d062..ff69f7746ae 100644 --- a/src/plugins/cpptools/cpptoolsplugin.cpp +++ b/src/plugins/cpptools/cpptoolsplugin.cpp @@ -129,7 +129,7 @@ bool CppToolsPlugin::initialize(const QStringList &arguments, QString *error) addAutoReleasedObject(new CppFunctionsFilter(locatorData)); addAutoReleasedObject(new CppCurrentDocumentFilter(modelManager)); addAutoReleasedObject(new CppFileSettingsPage(m_fileSettings)); -// addAutoReleasedObject(new CppCodeModelSettingsPage(m_codeModelSettings)); + addAutoReleasedObject(new CppCodeModelSettingsPage(m_codeModelSettings)); addAutoReleasedObject(new SymbolsFindFilter(modelManager)); addAutoReleasedObject(new CppCodeStyleSettingsPage); diff --git a/src/plugins/cpptools/cpptoolsplugin.h b/src/plugins/cpptools/cpptoolsplugin.h index b45631ab8d0..3a0c4b90241 100644 --- a/src/plugins/cpptools/cpptoolsplugin.h +++ b/src/plugins/cpptools/cpptoolsplugin.h @@ -212,6 +212,7 @@ private slots: void test_modelmanager_gc_if_last_cppeditor_closed(); void test_modelmanager_dont_gc_opened_files(); void test_modelmanager_defines_per_project(); + void test_modelmanager_defines_per_project_pch(); void test_cpplocatorfilters_CppLocatorFilter(); void test_cpplocatorfilters_CppLocatorFilter_data(); diff --git a/tests/cppmodelmanager/testdata_defines/pch1.h b/tests/cppmodelmanager/testdata_defines/pch1.h new file mode 100644 index 00000000000..a5a8cae412f --- /dev/null +++ b/tests/cppmodelmanager/testdata_defines/pch1.h @@ -0,0 +1 @@ +#define SUB1 diff --git a/tests/cppmodelmanager/testdata_defines/pch2.h b/tests/cppmodelmanager/testdata_defines/pch2.h new file mode 100644 index 00000000000..2b715eaec16 --- /dev/null +++ b/tests/cppmodelmanager/testdata_defines/pch2.h @@ -0,0 +1 @@ +#define SUB2