Commit 3d33886e authored by Erik Verbruggen's avatar Erik Verbruggen

C++: fix include/framework path handling.

Instead of having two lists of paths, now only one list is used where
both include paths and framework paths can be mixed. This reflects the
way the compiler is invoked, and retains the (correct) search order.

Task-number: QTCREATORBUG-11599
Change-Id: I373953e3e305df5b7a0d10920e12d146584adf9f
Reviewed-by: default avatarNikolai Kosjar <nikolai.kosjar@digia.com>
parent 76152088
...@@ -427,7 +427,10 @@ void AutotoolsProject::updateCppCodeModel() ...@@ -427,7 +427,10 @@ void AutotoolsProject::updateCppCodeModel()
foreach (const QString &file, m_files) foreach (const QString &file, m_files)
part->files << CppTools::ProjectFile(file, CppTools::ProjectFile::CXXSource); part->files << CppTools::ProjectFile(file, CppTools::ProjectFile::CXXSource);
part->includePaths += m_makefileParserThread->includePaths(); foreach (const QString &inc, m_makefileParserThread->includePaths()) {
part->headerPaths += CppTools::ProjectPart::HeaderPath(
inc, CppTools::ProjectPart::HeaderPath::IncludePath);
}
part->projectDefines += m_makefileParserThread->defines(); part->projectDefines += m_makefileParserThread->defines();
pinfo.appendProjectPart(part); pinfo.appendProjectPart(part);
......
...@@ -213,7 +213,8 @@ IAssistInterface *ClangCompletionAssistProvider::createAssistInterface( ...@@ -213,7 +213,8 @@ IAssistInterface *ClangCompletionAssistProvider::createAssistInterface(
QList<ProjectPart::Ptr> parts = modelManager->projectPart(fileName); QList<ProjectPart::Ptr> parts = modelManager->projectPart(fileName);
if (parts.isEmpty()) if (parts.isEmpty())
parts += modelManager->fallbackProjectPart(); parts += modelManager->fallbackProjectPart();
QStringList includePaths, frameworkPaths, options; ProjectPart::HeaderPaths headerPaths;
QStringList options;
PchInfo::Ptr pchInfo; PchInfo::Ptr pchInfo;
foreach (ProjectPart::Ptr part, parts) { foreach (ProjectPart::Ptr part, parts) {
if (part.isNull()) if (part.isNull())
...@@ -222,15 +223,14 @@ IAssistInterface *ClangCompletionAssistProvider::createAssistInterface( ...@@ -222,15 +223,14 @@ IAssistInterface *ClangCompletionAssistProvider::createAssistInterface(
pchInfo = PchManager::instance()->pchInfo(part); pchInfo = PchManager::instance()->pchInfo(part);
if (!pchInfo.isNull()) if (!pchInfo.isNull())
options.append(ClangCodeModel::Utils::createPCHInclusionOptions(pchInfo->fileName())); options.append(ClangCodeModel::Utils::createPCHInclusionOptions(pchInfo->fileName()));
includePaths = part->includePaths; headerPaths = part->headerPaths;
frameworkPaths = part->frameworkPaths;
break; break;
} }
return new ClangCodeModel::ClangCompletionAssistInterface( return new ClangCodeModel::ClangCompletionAssistInterface(
m_clangCompletionWrapper, m_clangCompletionWrapper,
document, position, fileName, reason, document, position, fileName, reason,
options, includePaths, frameworkPaths, pchInfo); options, headerPaths, pchInfo);
} }
// ------------------------ // ------------------------
...@@ -550,14 +550,12 @@ ClangCompletionAssistInterface::ClangCompletionAssistInterface(ClangCompleter::P ...@@ -550,14 +550,12 @@ ClangCompletionAssistInterface::ClangCompletionAssistInterface(ClangCompleter::P
const QString &fileName, const QString &fileName,
AssistReason reason, AssistReason reason,
const QStringList &options, const QStringList &options,
const QStringList &includePaths, const QList<CppTools::ProjectPart::HeaderPath> &headerPaths,
const QStringList &frameworkPaths,
const PchInfo::Ptr &pchInfo) const PchInfo::Ptr &pchInfo)
: DefaultAssistInterface(document, position, fileName, reason) : DefaultAssistInterface(document, position, fileName, reason)
, m_clangWrapper(clangWrapper) , m_clangWrapper(clangWrapper)
, m_options(options) , m_options(options)
, m_includePaths(includePaths) , m_headerPaths(headerPaths)
, m_frameworkPaths(frameworkPaths)
, m_savedPchPointer(pchInfo) , m_savedPchPointer(pchInfo)
{ {
Q_ASSERT(!clangWrapper.isNull()); Q_ASSERT(!clangWrapper.isNull());
...@@ -1138,29 +1136,22 @@ bool ClangCompletionAssistProcessor::completeInclude(const QTextCursor &cursor) ...@@ -1138,29 +1136,22 @@ bool ClangCompletionAssistProcessor::completeInclude(const QTextCursor &cursor)
} }
// Make completion for all relevant includes // Make completion for all relevant includes
QStringList includePaths = m_interface->includePaths(); ProjectPart::HeaderPaths headerPaths = m_interface->headerPaths();
const QString &currentFilePath = QFileInfo(m_interface->fileName()).path(); const ProjectPart::HeaderPath currentFilePath(QFileInfo(m_interface->fileName()).path(),
if (!includePaths.contains(currentFilePath)) ProjectPart::HeaderPath::IncludePath);
includePaths.append(currentFilePath); if (!headerPaths.contains(currentFilePath))
headerPaths.append(currentFilePath);
const Core::MimeType mimeType = Core::MimeDatabase::findByType(QLatin1String("text/x-c++hdr")); const Core::MimeType mimeType = Core::MimeDatabase::findByType(QLatin1String("text/x-c++hdr"));
const QStringList suffixes = mimeType.suffixes(); const QStringList suffixes = mimeType.suffixes();
foreach (const QString &includePath, includePaths) { foreach (const ProjectPart::HeaderPath &headerPath, headerPaths) {
QString realPath = includePath; QString realPath = headerPath.path;
if (!directoryPrefix.isEmpty()) { if (!directoryPrefix.isEmpty()) {
realPath += QLatin1Char('/'); realPath += QLatin1Char('/');
realPath += directoryPrefix; realPath += directoryPrefix;
} if (headerPath.isFrameworkPath())
completeIncludePath(realPath, suffixes); realPath += QLatin1String(".framework/Headers");
}
foreach (const QString &frameworkPath, m_interface->frameworkPaths()) {
QString realPath = frameworkPath;
if (!directoryPrefix.isEmpty()) {
realPath += QLatin1Char('/');
realPath += directoryPrefix;
realPath += QLatin1String(".framework/Headers");
} }
completeIncludePath(realPath, suffixes); completeIncludePath(realPath, suffixes);
} }
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include <cplusplus/Icons.h> #include <cplusplus/Icons.h>
#include <cpptools/cppcompletionassistprovider.h> #include <cpptools/cppcompletionassistprovider.h>
#include <cpptools/cppmodelmanagerinterface.h>
#include <texteditor/codeassist/basicproposalitem.h> #include <texteditor/codeassist/basicproposalitem.h>
#include <texteditor/codeassist/completionassistprovider.h> #include <texteditor/codeassist/completionassistprovider.h>
...@@ -76,8 +77,7 @@ public: ...@@ -76,8 +77,7 @@ public:
const QString &fileName, const QString &fileName,
TextEditor::AssistReason reason, TextEditor::AssistReason reason,
const QStringList &options, const QStringList &options,
const QStringList &includePaths, const QList<CppTools::ProjectPart::HeaderPath> &headerPaths,
const QStringList &frameworkPaths,
const Internal::PchInfo::Ptr &pchInfo); const Internal::PchInfo::Ptr &pchInfo);
ClangCodeModel::ClangCompleter::Ptr clangWrapper() const ClangCodeModel::ClangCompleter::Ptr clangWrapper() const
...@@ -91,16 +91,14 @@ public: ...@@ -91,16 +91,14 @@ public:
const QStringList &options() const const QStringList &options() const
{ return m_options; } { return m_options; }
const QStringList &includePaths() const const QList<CppTools::ProjectPart::HeaderPath> &headerPaths() const
{ return m_includePaths; } { return m_headerPaths; }
const QStringList &frameworkPaths() const
{ return m_frameworkPaths; }
private: private:
ClangCodeModel::ClangCompleter::Ptr m_clangWrapper; ClangCodeModel::ClangCompleter::Ptr m_clangWrapper;
ClangCodeModel::Internal::UnsavedFiles m_unsavedFiles; ClangCodeModel::Internal::UnsavedFiles m_unsavedFiles;
QStringList m_options, m_includePaths, m_frameworkPaths; QStringList m_options;
QList<CppTools::ProjectPart::HeaderPath> m_headerPaths;
Internal::PchInfo::Ptr m_savedPchPointer; Internal::PchInfo::Ptr m_savedPchPointer;
}; };
......
...@@ -209,11 +209,20 @@ QStringList createClangOptions(const ProjectPart::Ptr &pPart, ProjectFile::Kind ...@@ -209,11 +209,20 @@ QStringList createClangOptions(const ProjectPart::Ptr &pPart, ProjectFile::Kind
result << buildDefines(pPart->toolchainDefines, false); result << buildDefines(pPart->toolchainDefines, false);
result << buildDefines(pPart->projectDefines, false); result << buildDefines(pPart->projectDefines, false);
foreach (const QString &frameworkPath, pPart->frameworkPaths) typedef ProjectPart::HeaderPath HeaderPath;
result.append(QLatin1String("-F") + frameworkPath); foreach (const HeaderPath &headerPath , pPart->headerPaths) {
foreach (const QString &inc, pPart->includePaths) if (headerPath.path.isEmpty() || isBlacklisted(headerPath.path))
if (!inc.isEmpty() && !isBlacklisted(inc)) continue;
result << (QLatin1String("-I") + inc);
QString prefix;
switch (headerPath.type) {
case HeaderPath::IncludePath: prefix = QLatin1String("-I"); break;
case HeaderPath::FrameworkPath: prefix = QLatin1String("-F"); break;
default: Q_UNREACHABLE(); break;
}
result.append(prefix + headerPath.path);
}
#if 0 #if 0
qDebug() << "--- m_args:"; qDebug() << "--- m_args:";
......
...@@ -249,7 +249,8 @@ void PchManager::doPchInfoUpdateNone(QFutureInterface<void> &future, ...@@ -249,7 +249,8 @@ void PchManager::doPchInfoUpdateNone(QFutureInterface<void> &future,
void PchManager::doPchInfoUpdateFuzzy(QFutureInterface<void> &future, void PchManager::doPchInfoUpdateFuzzy(QFutureInterface<void> &future,
const PchManager::UpdateParams params) const PchManager::UpdateParams params)
{ {
QHash<QString, QSet<QString> > includes, frameworks; typedef ProjectPart::HeaderPath HeaderPath;
QHash<QString, QSet<HeaderPath>> headers;
QHash<QString, QSet<QByteArray> > definesPerPCH; QHash<QString, QSet<QByteArray> > definesPerPCH;
QHash<QString, bool> objc; QHash<QString, bool> objc;
QHash<QString, bool> cplusplus; QHash<QString, bool> cplusplus;
...@@ -266,8 +267,7 @@ void PchManager::doPchInfoUpdateFuzzy(QFutureInterface<void> &future, ...@@ -266,8 +267,7 @@ void PchManager::doPchInfoUpdateFuzzy(QFutureInterface<void> &future,
continue; continue;
inputToParts[pch].append(projectPart); inputToParts[pch].append(projectPart);
includes[pch].unite(QSet<QString>::fromList(projectPart->includePaths)); headers[pch].unite(QSet<HeaderPath>::fromList(projectPart->headerPaths));
frameworks[pch].unite(QSet<QString>::fromList(projectPart->frameworkPaths));
cVersions[pch] = std::max(cVersions.value(pch, ProjectPart::C89), projectPart->cVersion); cVersions[pch] = std::max(cVersions.value(pch, ProjectPart::C89), projectPart->cVersion);
cxxVersions[pch] = std::max(cxxVersions.value(pch, ProjectPart::CXX98), projectPart->cxxVersion); cxxVersions[pch] = std::max(cxxVersions.value(pch, ProjectPart::CXX98), projectPart->cxxVersion);
cxxExtensionsMap[pch] = cxxExtensionsMap[pch] | projectPart->cxxExtensions; cxxExtensionsMap[pch] = cxxExtensionsMap[pch] | projectPart->cxxExtensions;
...@@ -306,8 +306,7 @@ void PchManager::doPchInfoUpdateFuzzy(QFutureInterface<void> &future, ...@@ -306,8 +306,7 @@ void PchManager::doPchInfoUpdateFuzzy(QFutureInterface<void> &future,
projectPart->cVersion = cVersions[pch]; projectPart->cVersion = cVersions[pch];
projectPart->cxxVersion = cxxVersions[pch]; projectPart->cxxVersion = cxxVersions[pch];
projectPart->cxxExtensions = cxxExtensionsMap[pch]; projectPart->cxxExtensions = cxxExtensionsMap[pch];
projectPart->includePaths = includes[pch].toList(); projectPart->headerPaths = headers[pch].toList();
projectPart->frameworkPaths = frameworks[pch].toList();
QList<QByteArray> defines = definesPerPCH[pch].toList(); QList<QByteArray> defines = definesPerPCH[pch].toList();
if (!defines.isEmpty()) { if (!defines.isEmpty()) {
...@@ -378,22 +377,20 @@ void PchManager::doPchInfoUpdateCustom(QFutureInterface<void> &future, ...@@ -378,22 +377,20 @@ void PchManager::doPchInfoUpdateCustom(QFutureInterface<void> &future,
future.setProgressRange(0, 1); future.setProgressRange(0, 1);
future.setProgressValue(0); future.setProgressValue(0);
QSet<QString> includes, frameworks; ProjectPart::HeaderPaths headers;
bool objc = false; bool objc = false;
bool cplusplus = false; bool cplusplus = false;
ProjectPart::Ptr united(new ProjectPart()); ProjectPart::Ptr united(new ProjectPart());
united->cxxVersion = ProjectPart::CXX98; united->cxxVersion = ProjectPart::CXX98;
foreach (const ProjectPart::Ptr &projectPart, params.projectParts) { foreach (const ProjectPart::Ptr &projectPart, params.projectParts) {
includes.unite(QSet<QString>::fromList(projectPart->includePaths)); headers += projectPart->headerPaths;
frameworks.unite(QSet<QString>::fromList(projectPart->frameworkPaths));
united->cVersion = std::max(united->cVersion, projectPart->cVersion); united->cVersion = std::max(united->cVersion, projectPart->cVersion);
united->cxxVersion = std::max(united->cxxVersion, projectPart->cxxVersion); united->cxxVersion = std::max(united->cxxVersion, projectPart->cxxVersion);
united->qtVersion = std::max(united->qtVersion, projectPart->qtVersion); united->qtVersion = std::max(united->qtVersion, projectPart->qtVersion);
objc |= hasObjCFiles(projectPart); objc |= hasObjCFiles(projectPart);
cplusplus |= hasCppFiles(projectPart); cplusplus |= hasCppFiles(projectPart);
} }
united->frameworkPaths = frameworks.toList(); united->headerPaths = headers;
united->includePaths = includes.toList();
QStringList opts = Utils::createClangOptions( QStringList opts = Utils::createClangOptions(
united, getPrefixFileKind(objc, cplusplus)); united, getPrefixFileKind(objc, cplusplus));
united.clear(); united.clear();
......
...@@ -338,27 +338,32 @@ bool CMakeProject::parseCMakeLists() ...@@ -338,27 +338,32 @@ bool CMakeProject::parseCMakeLists()
CppTools::CppModelManagerInterface::ProjectInfo pinfo = modelmanager->projectInfo(this); CppTools::CppModelManagerInterface::ProjectInfo pinfo = modelmanager->projectInfo(this);
pinfo.clearProjectParts(); pinfo.clearProjectParts();
CppTools::ProjectPart::Ptr part(new CppTools::ProjectPart); typedef CppTools::ProjectPart ProjectPart;
ProjectPart::Ptr part(new ProjectPart);
part->project = this; part->project = this;
part->displayName = displayName(); part->displayName = displayName();
part->projectFile = projectFilePath().toString(); part->projectFile = projectFilePath().toString();
// This explicitly adds -I. to the include paths // This explicitly adds -I. to the include paths
part->includePaths += projectDirectory().toString(); part->headerPaths += ProjectPart::HeaderPath(projectDirectory().toString(),
ProjectPart::HeaderPath::IncludePath);
foreach (const QString &includeFile, cbpparser.includeFiles()) { foreach (const QString &includeFile, cbpparser.includeFiles()) {
ProjectPart::HeaderPath hp(includeFile, ProjectPart::HeaderPath::IncludePath);
// CodeBlocks is utterly ignorant of frameworks on Mac, and won't report framework // CodeBlocks is utterly ignorant of frameworks on Mac, and won't report framework
// paths. The work-around is to check if the include path ends in ".framework", and // paths. The work-around is to check if the include path ends in ".framework", and
// if so, add the parent directory as framework path. // if so, add the parent directory as framework path.
if (includeFile.endsWith(QLatin1String(".framework"))) { if (includeFile.endsWith(QLatin1String(".framework"))) {
const int slashIdx = includeFile.lastIndexOf(QLatin1Char('/')); const int slashIdx = includeFile.lastIndexOf(QLatin1Char('/'));
if (slashIdx != -1) { if (slashIdx != -1) {
part->frameworkPaths += includeFile.left(slashIdx); hp = ProjectPart::HeaderPath(includeFile.left(slashIdx),
ProjectPart::HeaderPath::FrameworkPath);
continue; continue;
} }
} }
part->includePaths += includeFile; part->headerPaths += hp;
} }
part->projectDefines += cbpparser.defines(); part->projectDefines += cbpparser.defines();
......
...@@ -1446,7 +1446,7 @@ void CppCodeModelInspectorDialog::refresh() ...@@ -1446,7 +1446,7 @@ void CppCodeModelInspectorDialog::refresh()
} }
// Merged entities // Merged entities
dumper.dumpMergedEntities(cmmi->includePaths(), cmmi->frameworkPaths(), cmmi->definedMacros()); dumper.dumpMergedEntities(cmmi->headerPaths(), cmmi->definedMacros());
} }
enum DocumentTabs { enum DocumentTabs {
...@@ -1559,8 +1559,7 @@ enum ProjectPartTabs { ...@@ -1559,8 +1559,7 @@ enum ProjectPartTabs {
ProjectPartGeneralTab, ProjectPartGeneralTab,
ProjectPartFilesTab, ProjectPartFilesTab,
ProjectPartDefinesTab, ProjectPartDefinesTab,
ProjectPartIncludePathsTab, ProjectPartHeaderPathsTab,
ProjectPartFrameworkPathsTab,
ProjectPartPrecompiledHeadersTab ProjectPartPrecompiledHeadersTab
}; };
...@@ -1570,8 +1569,7 @@ static QString partTabName(int tabIndex, int numberOfEntries = -1) ...@@ -1570,8 +1569,7 @@ static QString partTabName(int tabIndex, int numberOfEntries = -1)
"&General", "&General",
"Project &Files", "Project &Files",
"&Defines", "&Defines",
"&Include Paths", "&Header Paths",
"F&ramework Paths",
"Pre&compiled Headers" "Pre&compiled Headers"
}; };
QString result = QLatin1String(names[tabIndex]); QString result = QLatin1String(names[tabIndex]);
...@@ -1591,13 +1589,9 @@ void CppCodeModelInspectorDialog::clearProjectPartData() ...@@ -1591,13 +1589,9 @@ void CppCodeModelInspectorDialog::clearProjectPartData()
m_ui->partProjectDefinesEdit->setPlainText(QString()); m_ui->partProjectDefinesEdit->setPlainText(QString());
m_ui->projectPartTab->setTabText(ProjectPartDefinesTab, partTabName(ProjectPartDefinesTab)); m_ui->projectPartTab->setTabText(ProjectPartDefinesTab, partTabName(ProjectPartDefinesTab));
m_ui->partIncludePathsEdit->setPlainText(QString()); m_ui->partHeaderPathsEdit->setPlainText(QString());
m_ui->projectPartTab->setTabText(ProjectPartIncludePathsTab, m_ui->projectPartTab->setTabText(ProjectPartHeaderPathsTab,
partTabName(ProjectPartIncludePathsTab)); partTabName(ProjectPartHeaderPathsTab));
m_ui->partFrameworkPathsEdit->setPlainText(QString());
m_ui->projectPartTab->setTabText(ProjectPartFrameworkPathsTab,
partTabName(ProjectPartFrameworkPathsTab));
m_ui->partPrecompiledHeadersEdit->setPlainText(QString()); m_ui->partPrecompiledHeadersEdit->setPlainText(QString());
m_ui->projectPartTab->setTabText(ProjectPartPrecompiledHeadersTab, m_ui->projectPartTab->setTabText(ProjectPartPrecompiledHeadersTab,
...@@ -1654,15 +1648,10 @@ void CppCodeModelInspectorDialog::updateProjectPartData(const ProjectPart::Ptr & ...@@ -1654,15 +1648,10 @@ void CppCodeModelInspectorDialog::updateProjectPartData(const ProjectPart::Ptr &
m_ui->projectPartTab->setTabText(ProjectPartDefinesTab, m_ui->projectPartTab->setTabText(ProjectPartDefinesTab,
partTabName(ProjectPartDefinesTab, numberOfDefines)); partTabName(ProjectPartDefinesTab, numberOfDefines));
// Include Paths // Header Paths
m_ui->partIncludePathsEdit->setPlainText(CMI::Utils::pathListToString(part->includePaths)); m_ui->partHeaderPathsEdit->setPlainText(CMI::Utils::pathListToString(part->headerPaths));
m_ui->projectPartTab->setTabText(ProjectPartIncludePathsTab, m_ui->projectPartTab->setTabText(ProjectPartHeaderPathsTab,
partTabName(ProjectPartIncludePathsTab, part->includePaths.size())); partTabName(ProjectPartHeaderPathsTab, part->headerPaths.size()));
// Framework Paths
m_ui->partFrameworkPathsEdit->setPlainText(CMI::Utils::pathListToString(part->frameworkPaths));
m_ui->projectPartTab->setTabText(ProjectPartFrameworkPathsTab,
partTabName(ProjectPartFrameworkPathsTab, part->frameworkPaths.size()));
// Precompiled Headers // Precompiled Headers
m_ui->partPrecompiledHeadersEdit->setPlainText( m_ui->partPrecompiledHeadersEdit->setPlainText(
......
...@@ -261,25 +261,11 @@ ...@@ -261,25 +261,11 @@
</widget> </widget>
<widget class="QWidget" name="tab_15"> <widget class="QWidget" name="tab_15">
<attribute name="title"> <attribute name="title">
<string notr="true">&amp;Include Paths</string> <string notr="true">&amp;Header Paths</string>
</attribute> </attribute>
<layout class="QVBoxLayout" name="verticalLayout_16"> <layout class="QVBoxLayout" name="verticalLayout_16">
<item> <item>
<widget class="QPlainTextEdit" name="partIncludePathsEdit"> <widget class="QPlainTextEdit" name="partHeaderPathsEdit">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="definesTab_2">
<attribute name="title">
<string notr="true">F&amp;ramework Paths</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_17">
<item>
<widget class="QPlainTextEdit" name="partFrameworkPathsEdit">
<property name="readOnly"> <property name="readOnly">
<bool>true</bool> <bool>true</bool>
</property> </property>
......
This diff is collapsed.
...@@ -74,10 +74,13 @@ class QuickFixTestCase : public TestCase ...@@ -74,10 +74,13 @@ class QuickFixTestCase : public TestCase
public: public:
QuickFixTestCase(const QList<QuickFixTestDocument::Ptr> &theTestFiles, QuickFixTestCase(const QList<QuickFixTestDocument::Ptr> &theTestFiles,
CppQuickFixFactory *factory, CppQuickFixFactory *factory,
const QStringList &includePaths = QStringList(), const CppTools::ProjectPart::HeaderPaths &includePaths =
CppTools::ProjectPart::HeaderPaths(),
int resultIndex = 0); int resultIndex = 0);
~QuickFixTestCase(); ~QuickFixTestCase();
static void run(const QList<QuickFixTestDocument::Ptr> &theTestFiles,
CppQuickFixFactory *factory, const QString &incPath);
private: private:
QSharedPointer<TextEditor::QuickFixOperation> getFix(CppQuickFixFactory *factory, QSharedPointer<TextEditor::QuickFixOperation> getFix(CppQuickFixFactory *factory,
CPPEditorWidget *editorWidget, CPPEditorWidget *editorWidget,
...@@ -89,8 +92,8 @@ private: ...@@ -89,8 +92,8 @@ private:
CppTools::CppCodeStylePreferences *m_cppCodeStylePreferences; CppTools::CppCodeStylePreferences *m_cppCodeStylePreferences;
QByteArray m_cppCodeStylePreferencesOriginalDelegateId; QByteArray m_cppCodeStylePreferencesOriginalDelegateId;
QStringList m_includePathsToRestore; CppTools::ProjectPart::HeaderPaths m_headerPathsToRestore;
bool m_restoreIncludePaths; bool m_restoreHeaderPaths;
}; };
QList<QuickFixTestDocument::Ptr> singleDocument(const QByteArray &original, QList<QuickFixTestDocument::Ptr> singleDocument(const QByteArray &original,
......
...@@ -1896,7 +1896,7 @@ void AddIncludeForUndefinedIdentifier::match(const CppQuickFixInterface &interfa ...@@ -1896,7 +1896,7 @@ void AddIncludeForUndefinedIdentifier::match(const CppQuickFixInterface &interfa
return; return;
// find the include paths // find the include paths
QStringList includePaths; ProjectPart::HeaderPaths headerPaths;
CppModelManagerInterface *modelManager = CppModelManagerInterface::instance(); CppModelManagerInterface *modelManager = CppModelManagerInterface::instance();
QList<CppModelManagerInterface::ProjectInfo> projectInfos = modelManager->projectInfos(); QList<CppModelManagerInterface::ProjectInfo> projectInfos = modelManager->projectInfos();
bool inProject = false; bool inProject = false;
...@@ -1905,14 +1905,14 @@ void AddIncludeForUndefinedIdentifier::match(const CppQuickFixInterface &interfa ...@@ -1905,14 +1905,14 @@ void AddIncludeForUndefinedIdentifier::match(const CppQuickFixInterface &interfa
foreach (const ProjectFile &file, part->files) { foreach (const ProjectFile &file, part->files) {
if (file.path == doc->fileName()) { if (file.path == doc->fileName()) {
inProject = true; inProject = true;
includePaths += part->includePaths; headerPaths += part->headerPaths;
} }
} }
} }
} }
if (!inProject) { if (!inProject) {
// better use all include paths than none // better use all include paths than none
includePaths = modelManager->includePaths(); headerPaths = modelManager->headerPaths();
} }
// find a include file through the locator // find a include file through the locator
...@@ -1933,10 +1933,10 @@ void AddIncludeForUndefinedIdentifier::match(const CppQuickFixInterface &interfa ...@@ -1933,10 +1933,10 @@ void AddIncludeForUndefinedIdentifier::match(const CppQuickFixInterface &interfa
if (fileInfo.path() == QFileInfo(doc->fileName()).path()) { if (fileInfo.path() == QFileInfo(doc->fileName()).path()) {
shortestInclude = QLatin1Char('"') + fileInfo.fileName() + QLatin1Char('"'); shortestInclude = QLatin1Char('"') + fileInfo.fileName() + QLatin1Char('"');
} else { } else {
foreach (const QString &includePath, includePaths) { foreach (const ProjectPart::HeaderPath &headerPath, headerPaths) {
if (!fileName.startsWith(includePath)) if (!fileName.startsWith(headerPath.path))
continue; continue;
QString relativePath = fileName.mid(includePath.size()); QString relativePath = fileName.mid(headerPath.path.size());
if (!relativePath.isEmpty() && relativePath.at(0) == QLatin1Char('/')) if (!relativePath.isEmpty() && relativePath.at(0) == QLatin1Char('/'))
relativePath = relativePath.mid(1); relativePath = relativePath.mid(1);
if (shortestInclude.isEmpty() || relativePath.size() + 2 < shortestInclude.size()) if (shortestInclude.isEmpty() || relativePath.size() + 2 < shortestInclude.size())
...@@ -1965,11 +1965,11 @@ void AddIncludeForUndefinedIdentifier::match(const CppQuickFixInterface &interfa ...@@ -1965,11 +1965,11 @@ void AddIncludeForUndefinedIdentifier::match(const CppQuickFixInterface &interfa
// otherwise, check for a header file with the same name in the Qt include paths // otherwise, check for a header file with the same name in the Qt include paths
} else { } else {
foreach (const QString &includePath, includePaths) { foreach (const ProjectPart::HeaderPath &headerPath, headerPaths) {
if (!includePath.contains(QLatin1String("/Qt"))) // "QtCore", "QtGui" etc... if (!headerPath.path.contains(QLatin1String("/Qt"))) // "QtCore", "QtGui" etc...
continue; continue;
const QString headerPathCandidate = includePath + QLatin1Char('/') + className; const QString headerPathCandidate = headerPath.path + QLatin1Char('/') + className;
const QFileInfo fileInfo(headerPathCandidate);