CppTools: Auto-include pre-compiled headers

So far the pre-compiled headers were processed (thus defines from those
headers were visible), but the actual includes for the documents were
not added, which is necessary for lookup/completion.

Note that this will be only done if pre-compiled headers are not ignored
(Options > C++ > Code Model > [] Ignore pre-compiled headers).

Change-Id: I54a8e6b00597af164d958e3e9f2a1075ea187788
Reviewed-by: Erik Verbruggen <erik.verbruggen@digia.com>
This commit is contained in:
Nikolai Kosjar
2014-07-16 11:25:15 +02:00
parent 4e9d3b044e
commit 6a9ae7e25f
11 changed files with 51 additions and 20 deletions

View File

@@ -66,9 +66,10 @@ QByteArray FastPreprocessor::run(Document::Ptr newDoc, const QByteArray &source)
return preprocessed; return preprocessed;
} }
void FastPreprocessor::sourceNeeded(unsigned line, const QString &fileName, void FastPreprocessor::sourceNeeded(unsigned line, const QString &fileName, IncludeType mode,
IncludeType mode) const QStringList &initialIncludes)
{ {
Q_UNUSED(initialIncludes)
Q_ASSERT(_currentDoc); Q_ASSERT(_currentDoc);
// CHECKME: Is that cleanName needed? // CHECKME: Is that cleanName needed?
QString cleanName = QDir::cleanPath(fileName); QString cleanName = QDir::cleanPath(fileName);

View File

@@ -57,7 +57,8 @@ public:
QByteArray run(Document::Ptr newDoc, const QByteArray &source); QByteArray run(Document::Ptr newDoc, const QByteArray &source);
// CPlusPlus::Client // CPlusPlus::Client
virtual void sourceNeeded(unsigned line, const QString &fileName, IncludeType mode); virtual void sourceNeeded(unsigned line, const QString &fileName, IncludeType mode,
const QStringList &initialIncludes = QStringList());
virtual void macroAdded(const Macro &); virtual void macroAdded(const Macro &);

View File

@@ -32,7 +32,7 @@
#include <cplusplus/CPlusPlusForwardDeclarations.h> #include <cplusplus/CPlusPlusForwardDeclarations.h>
#include <QString> #include <QStringList>
#include <QVector> #include <QVector>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@@ -100,7 +100,8 @@ public:
virtual void startSkippingBlocks(unsigned utf16charsOffset) = 0; virtual void startSkippingBlocks(unsigned utf16charsOffset) = 0;
virtual void stopSkippingBlocks(unsigned utf16charsOffset) = 0; virtual void stopSkippingBlocks(unsigned utf16charsOffset) = 0;
virtual void sourceNeeded(unsigned line, const QString &fileName, IncludeType mode) = 0; virtual void sourceNeeded(unsigned line, const QString &fileName, IncludeType mode,
const QStringList &initialIncludes = QStringList()) = 0;
static inline bool isInjectedFile(const QString &fileName) static inline bool isInjectedFile(const QString &fileName)
{ {

View File

@@ -37,6 +37,8 @@
#include <coreplugin/testdatadir.h> #include <coreplugin/testdatadir.h>
#include <projectexplorer/projectexplorer.h> #include <projectexplorer/projectexplorer.h>
#include <projectexplorer/session.h> #include <projectexplorer/session.h>
#include <cplusplus/LookupContext.h>
#include <utils/hostosinfo.h> #include <utils/hostosinfo.h>
#include <QDebug> #include <QDebug>
@@ -873,7 +875,7 @@ void CppToolsPlugin::test_modelmanager_defines_per_project()
} }
} }
void CppToolsPlugin::test_modelmanager_defines_per_project_pch() void CppToolsPlugin::test_modelmanager_precompiled_headers()
{ {
ModelManagerTestHelper helper; ModelManagerTestHelper helper;
@@ -922,14 +924,16 @@ void CppToolsPlugin::test_modelmanager_defines_per_project_pch()
struct Data { struct Data {
QString firstDeclarationName; QString firstDeclarationName;
QString firstClassInPchFile;
QString fileName; QString fileName;
} d[] = { } d[] = {
{ _("one"), main1File }, { _("one"), _("ClassInPch1"), main1File },
{ _("two"), main2File } { _("two"), _("ClassInPch2"), main2File }
}; };
const int size = sizeof(d) / sizeof(d[0]); const int size = sizeof(d) / sizeof(d[0]);
for (int i = 0; i < size; ++i) { for (int i = 0; i < size; ++i) {
const QString firstDeclarationName = d[i].firstDeclarationName; const QString firstDeclarationName = d[i].firstDeclarationName;
const QByteArray firstClassInPchFile = d[i].firstClassInPchFile.toUtf8();
const QString fileName = d[i].fileName; const QString fileName = d[i].fileName;
Core::IEditor *editor = Core::EditorManager::openEditor(fileName); Core::IEditor *editor = Core::EditorManager::openEditor(fileName);
@@ -943,11 +947,22 @@ void CppToolsPlugin::test_modelmanager_defines_per_project_pch()
while (sup->lastSemanticInfoDocument().isNull()) while (sup->lastSemanticInfoDocument().isNull())
QCoreApplication::processEvents(); QCoreApplication::processEvents();
sup->snapshotUpdater()->setUsePrecompiledHeaders(true); const QSharedPointer<SnapshotUpdater> updater = sup->snapshotUpdater();
sup->snapshotUpdater()->update(mm->workingCopy()); updater->setUsePrecompiledHeaders(true);
updater->update(mm->workingCopy());
Document::Ptr doc = mm->document(fileName); // Check if defines from pch are considered
QCOMPARE(nameOfFirstDeclaration(doc), firstDeclarationName); Document::Ptr document = mm->document(fileName);
QCOMPARE(nameOfFirstDeclaration(document), firstDeclarationName);
// Check if declarations from pch are considered
CPlusPlus::LookupContext context(document, updater->snapshot());
const CPlusPlus::Identifier *identifier
= document->control()->identifier(firstClassInPchFile.data());
const QList<CPlusPlus::LookupItem> results = context.lookup(identifier,
document->globalNamespace());
QVERIFY(!results.isEmpty());
QVERIFY(results.first().declaration()->type()->asClassType());
} }
} }

View File

@@ -177,7 +177,8 @@ void SnapshotUpdater::update(CppModelManager::WorkingCopy workingCopy)
} }
if (!m_editorDefines.isEmpty()) if (!m_editorDefines.isEmpty())
sourceProcessor.run(editorDefinesFileName); sourceProcessor.run(editorDefinesFileName);
sourceProcessor.run(m_fileInEditor); sourceProcessor.run(m_fileInEditor, m_usePrecompiledHeaders ? m_precompiledHeaders
: QStringList());
m_snapshot = sourceProcessor.snapshot(); m_snapshot = sourceProcessor.snapshot();
Snapshot newSnapshot = m_snapshot.simplified(document()); Snapshot newSnapshot = m_snapshot.simplified(document());

View File

@@ -148,9 +148,10 @@ void CppSourceProcessor::addFrameworkPath(const ProjectPart::HeaderPath &framewo
void CppSourceProcessor::setTodo(const QStringList &files) void CppSourceProcessor::setTodo(const QStringList &files)
{ m_todo = QSet<QString>::fromList(files); } { m_todo = QSet<QString>::fromList(files); }
void CppSourceProcessor::run(const QString &fileName) void CppSourceProcessor::run(const QString &fileName,
const QStringList &initialIncludes)
{ {
sourceNeeded(0, fileName, IncludeGlobal); sourceNeeded(0, fileName, IncludeGlobal, initialIncludes);
} }
void CppSourceProcessor::removeFromCache(const QString &fileName) void CppSourceProcessor::removeFromCache(const QString &fileName)
@@ -377,7 +378,8 @@ void CppSourceProcessor::stopSkippingBlocks(unsigned utf16charsOffset)
m_currentDoc->stopSkippingBlocks(utf16charsOffset); m_currentDoc->stopSkippingBlocks(utf16charsOffset);
} }
void CppSourceProcessor::sourceNeeded(unsigned line, const QString &fileName, IncludeType type) void CppSourceProcessor::sourceNeeded(unsigned line, const QString &fileName, IncludeType type,
const QStringList &initialIncludes)
{ {
if (fileName.isEmpty()) if (fileName.isEmpty())
return; return;
@@ -417,6 +419,11 @@ void CppSourceProcessor::sourceNeeded(unsigned line, const QString &fileName, In
Document::Ptr document = Document::create(absoluteFileName); Document::Ptr document = Document::create(absoluteFileName);
document->setRevision(m_revision); document->setRevision(m_revision);
document->setEditorRevision(editorRevision); document->setEditorRevision(editorRevision);
foreach (const QString &include, initialIncludes) {
m_included.insert(include);
Document::Include inc(include, include, 0, IncludeLocal);
document->addIncludeFile(inc);
}
const QFileInfo info(absoluteFileName); const QFileInfo info(absoluteFileName);
if (info.exists()) if (info.exists())
document->setLastModified(info.lastModified()); document->setLastModified(info.lastModified());

View File

@@ -43,7 +43,7 @@ public:
void setHeaderPaths(const ProjectPart::HeaderPaths &headerPaths); void setHeaderPaths(const ProjectPart::HeaderPaths &headerPaths);
void setTodo(const QStringList &files); void setTodo(const QStringList &files);
void run(const QString &fileName); void run(const QString &fileName, const QStringList &initialIncludes = QStringList());
void removeFromCache(const QString &fileName); void removeFromCache(const QString &fileName);
void resetEnvironment(); void resetEnvironment();
@@ -80,7 +80,8 @@ private:
void markAsIncludeGuard(const QByteArray &macroName) QTC_OVERRIDE; void markAsIncludeGuard(const QByteArray &macroName) QTC_OVERRIDE;
void startSkippingBlocks(unsigned utf16charsOffset) QTC_OVERRIDE; void startSkippingBlocks(unsigned utf16charsOffset) QTC_OVERRIDE;
void stopSkippingBlocks(unsigned utf16charsOffset) QTC_OVERRIDE; void stopSkippingBlocks(unsigned utf16charsOffset) QTC_OVERRIDE;
void sourceNeeded(unsigned line, const QString &fileName, IncludeType type) QTC_OVERRIDE; void sourceNeeded(unsigned line, const QString &fileName, IncludeType type,
const QStringList &initialIncludes) QTC_OVERRIDE;
private: private:
CPlusPlus::Snapshot m_snapshot; CPlusPlus::Snapshot m_snapshot;

View File

@@ -146,8 +146,8 @@ private slots:
void test_modelmanager_gc_if_last_cppeditor_closed(); void test_modelmanager_gc_if_last_cppeditor_closed();
void test_modelmanager_dont_gc_opened_files(); void test_modelmanager_dont_gc_opened_files();
void test_modelmanager_defines_per_project(); void test_modelmanager_defines_per_project();
void test_modelmanager_defines_per_project_pch();
void test_modelmanager_defines_per_editor(); void test_modelmanager_defines_per_editor();
void test_modelmanager_precompiled_headers();
void test_cpplocatorfilters_CppLocatorFilter(); void test_cpplocatorfilters_CppLocatorFilter();
void test_cpplocatorfilters_CppLocatorFilter_data(); void test_cpplocatorfilters_CppLocatorFilter_data();

View File

@@ -159,8 +159,10 @@ public:
virtual void stopSkippingBlocks(unsigned utf16charsOffset) virtual void stopSkippingBlocks(unsigned utf16charsOffset)
{ m_skippedBlocks.last().end = utf16charsOffset; } { m_skippedBlocks.last().end = utf16charsOffset; }
virtual void sourceNeeded(unsigned line, const QString &includedFileName, IncludeType mode) virtual void sourceNeeded(unsigned line, const QString &includedFileName, IncludeType mode,
const QStringList &initialIncludes = QStringList())
{ {
Q_UNUSED(initialIncludes)
#if 1 #if 1
m_recordedIncludes.append(Include(includedFileName, mode, line)); m_recordedIncludes.append(Include(includedFileName, mode, line));
Q_UNUSED(m_env); Q_UNUSED(m_env);

View File

@@ -1 +1,2 @@
#define SUB1 #define SUB1
class ClassInPch1{};

View File

@@ -1 +1,2 @@
#define SUB2 #define SUB2
class ClassInPch2{};