From 3aab8beaf4c585e66179f14fac2f63b51f034520 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen <erik.verbruggen@nokia.com> Date: Thu, 16 Feb 2012 15:09:56 +0100 Subject: [PATCH] Supply c++11 flags and per-project info to c++ code model. A manual squash/merge of the changes below, plus a couple of subsequent code fixes. 59085aa5fbb99e2d786cd2c1a06c24a111ccb49f: Modify CppModel::ProjectInfo Adding per project node information, to pass on the correct defines/includes for each file, instead of aggregating them incorrectly. Also split up SOURCES and OBJECTIVE_SOURCES. Also ask the toolchain to convert the compilerflags to flags the codemodel understands, for now only gcc and only c++11. Also make the toolchain aware of the flags used to compile, so that it can emit the correct defines. Note: No header files are passed on. 74028802314cd4e75b41b46407433e07090a304d: GCC: Evaluate cxxflags when checking for predefined macros ebaaa4957e4c02cc9637a998eddae1d0acd74f83: MSVC: Take cxxflags into account when checking for predefined macros 9bfce7e889bcf7bcc47bf880e3ea25945ca7d0d7: Compile fixes Change-Id: I9de94ad038dfc5dc1987732e84b13fb4419c96f5 Reviewed-by: Erik Verbruggen <erik.verbruggen@nokia.com> --- src/libs/cplusplus/ModelManagerInterface.cpp | 43 +++++ src/libs/cplusplus/ModelManagerInterface.h | 88 +++++++++-- .../autotoolsproject.cpp | 26 +-- .../cmakeprojectmanager/cmakeproject.cpp | 23 +-- src/plugins/cppeditor/cppquickfixes.cpp | 14 +- src/plugins/cpptools/cppcompletionsupport.cpp | 4 +- src/plugins/cpptools/cppmodelmanager.cpp | 95 ++++++++++- src/plugins/cpptools/cppmodelmanager.h | 5 +- src/plugins/cpptools/cpptoolsreuse.cpp | 21 ++- src/plugins/cpptools/cpptoolsreuse.h | 1 + .../genericprojectmanager/genericproject.cpp | 23 +-- .../projectexplorer/abstractmsvctoolchain.cpp | 16 +- .../projectexplorer/abstractmsvctoolchain.h | 8 +- src/plugins/projectexplorer/gcctoolchain.cpp | 45 +++++- src/plugins/projectexplorer/gcctoolchain.h | 4 +- src/plugins/projectexplorer/msvctoolchain.cpp | 50 ++++-- src/plugins/projectexplorer/msvctoolchain.h | 3 +- src/plugins/projectexplorer/toolchain.h | 8 +- .../qt-s60/gccetoolchain.cpp | 4 +- .../qt4projectmanager/qt-s60/gccetoolchain.h | 2 +- .../qt-s60/rvcttoolchain.cpp | 9 +- .../qt4projectmanager/qt-s60/rvcttoolchain.h | 3 +- .../qt-s60/winscwtoolchain.cpp | 9 +- .../qt-s60/winscwtoolchain.h | 3 +- src/plugins/qt4projectmanager/qt4nodes.cpp | 30 ++++ src/plugins/qt4projectmanager/qt4nodes.h | 4 + src/plugins/qt4projectmanager/qt4project.cpp | 149 +++++++----------- src/plugins/texteditor/basetexteditor.cpp | 2 +- src/plugins/texteditor/basetexteditor.h | 2 +- .../texteditor/codeassist/genericproposal.h | 2 +- src/plugins/texteditor/semantichighlighter.h | 6 + 31 files changed, 513 insertions(+), 189 deletions(-) diff --git a/src/libs/cplusplus/ModelManagerInterface.cpp b/src/libs/cplusplus/ModelManagerInterface.cpp index 5dfce63cc96..18443186df8 100644 --- a/src/libs/cplusplus/ModelManagerInterface.cpp +++ b/src/libs/cplusplus/ModelManagerInterface.cpp @@ -32,6 +32,8 @@ #include "ModelManagerInterface.h" +#include <QtCore/QSet> + using namespace CPlusPlus; static CppModelManagerInterface *g_instance = 0; @@ -54,3 +56,44 @@ CppModelManagerInterface *CppModelManagerInterface::instance() return g_instance; } + +void CppModelManagerInterface::ProjectInfo::clearProjectParts() +{ + m_projectParts.clear(); + m_includePaths.clear(); + m_frameworkPaths.clear(); + m_sourceFiles.clear(); + m_defines.clear(); +} + +void CppModelManagerInterface::ProjectInfo::appendProjectPart( + const CppModelManagerInterface::ProjectPart::Ptr &part) +{ + if (!part) + return; + + m_projectParts.append(part); + + // update include paths + QSet<QString> incs = QSet<QString>::fromList(m_includePaths); + foreach (const QString &ins, part->includePaths) + incs.insert(ins); + m_includePaths = incs.toList(); + + // update framework paths + QSet<QString> frms = QSet<QString>::fromList(m_frameworkPaths); + foreach (const QString &frm, part->frameworkPaths) + frms.insert(frm); + m_frameworkPaths = frms.toList(); + + // update source files + QSet<QString> srcs = QSet<QString>::fromList(m_sourceFiles); + foreach (const QString &src, part->sourceFiles) + srcs.insert(src); + m_sourceFiles = srcs.toList(); + + // update defines + if (!m_defines.isEmpty()) + m_defines.append('\n'); + m_defines.append(part->defines); +} diff --git a/src/libs/cplusplus/ModelManagerInterface.h b/src/libs/cplusplus/ModelManagerInterface.h index a057a601dae..06ab239c68b 100644 --- a/src/libs/cplusplus/ModelManagerInterface.h +++ b/src/libs/cplusplus/ModelManagerInterface.h @@ -35,6 +35,9 @@ #include <cplusplus/CppDocument.h> #include <languageutils/fakemetaobject.h> +#include <projectexplorer/project.h> +#include <projectexplorer/toolchain.h> + #include <QObject> #include <QHash> #include <QPointer> @@ -66,33 +69,88 @@ class CPLUSPLUS_EXPORT CppModelManagerInterface : public QObject Q_OBJECT public: + enum Language { CXX, OBJC }; + + class CPLUSPLUS_EXPORT ProjectPart + { + public: + ProjectPart() + : qtVersion(UnknownQt) + {} + + public: //attributes + QStringList sourceFiles; + QByteArray defines; + QStringList includePaths; + QStringList frameworkPaths; + QStringList precompiledHeaders; + Language language; + ProjectExplorer::ToolChain::CompilerFlags flags; + enum QtVersion { + UnknownQt = -1, + NoQt = 0, + Qt4 = 1, + Qt5 = 2 + }; + QtVersion qtVersion; + + bool cpp0xEnabled() const + { return flags == ProjectExplorer::ToolChain::STD_CXX11; } + + bool objcEnabled() const + { return language == CppModelManagerInterface::OBJC; } + + typedef QSharedPointer<ProjectPart> Ptr; + }; + class ProjectInfo { public: ProjectInfo() { } - ProjectInfo(QPointer<ProjectExplorer::Project> project) - : project(project) + ProjectInfo(QWeakPointer<ProjectExplorer::Project> project) + : m_project(project) { } operator bool() const - { return ! project.isNull(); } + { return ! m_project.isNull(); } bool isValid() const - { return ! project.isNull(); } + { return ! m_project.isNull(); } bool isNull() const - { return project.isNull(); } + { return m_project.isNull(); } - public: // attributes - QPointer<ProjectExplorer::Project> project; - QString projectPath; - QByteArray defines; - QStringList sourceFiles; - QStringList includePaths; - QStringList frameworkPaths; - QStringList precompiledHeaders; + QWeakPointer<ProjectExplorer::Project> project() const + { return m_project; } + + const QList<ProjectPart::Ptr> projectParts() const + { return m_projectParts; } + + void clearProjectParts(); + void appendProjectPart(const ProjectPart::Ptr &part); + + const QStringList includePaths() const + { return m_includePaths; } + + const QStringList frameworkPaths() const + { return m_frameworkPaths; } + + const QStringList sourceFiles() const + { return m_sourceFiles; } + + const QByteArray defines() const + { return m_defines; } + + private: // attributes + QWeakPointer<ProjectExplorer::Project> m_project; + QList<ProjectPart::Ptr> m_projectParts; + // the attributes below are calculated from the project parts. + QStringList m_includePaths; + QStringList m_frameworkPaths; + QStringList m_sourceFiles; + QByteArray m_defines; }; class WorkingCopy @@ -110,6 +168,9 @@ public: QPair<QString, unsigned> get(const QString &fileName) const { return _elements.value(fileName); } + QHashIterator<QString, QPair<QString, unsigned> > iterator() const + { return QHashIterator<QString, QPair<QString, unsigned> >(_elements); } + private: typedef QHash<QString, QPair<QString, unsigned> > Table; Table _elements; @@ -135,6 +196,7 @@ public: virtual QList<ProjectInfo> projectInfos() const = 0; virtual ProjectInfo projectInfo(ProjectExplorer::Project *project) const = 0; virtual void updateProjectInfo(const ProjectInfo &pinfo) = 0; + virtual QList<ProjectPart::Ptr> projectPart(const QString &fileName) const = 0; virtual void addEditorSupport(CppTools::AbstractEditorSupport *editorSupport) = 0; virtual void removeEditorSupport(CppTools::AbstractEditorSupport *editorSupport) = 0; diff --git a/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp b/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp index 015a3030017..e6fd4e7d3de 100644 --- a/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp +++ b/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp @@ -513,19 +513,23 @@ void AutotoolsProject::updateCppCodeModel() CPlusPlus::CppModelManagerInterface::ProjectInfo pinfo = modelManager->projectInfo(this); - const bool update = (pinfo.includePaths != allIncludePaths) - || (pinfo.sourceFiles != m_files) - || (pinfo.defines != m_toolChain->predefinedMacros()) - || (pinfo.frameworkPaths != allFrameworkPaths); + const bool update = (pinfo.includePaths() != allIncludePaths) + || (pinfo.sourceFiles() != m_files) + || (pinfo.defines() != m_toolChain->predefinedMacros(QStringList())) + || (pinfo.frameworkPaths() != allFrameworkPaths); if (update) { - pinfo.includePaths = allIncludePaths; - pinfo.sourceFiles = m_files; + pinfo.clearProjectParts(); + CPlusPlus::CppModelManagerInterface::ProjectPart::Ptr part( + new CPlusPlus::CppModelManagerInterface::ProjectPart); + part->includePaths = allIncludePaths; + part->sourceFiles = m_files; if (m_toolChain) - pinfo.defines = m_toolChain->predefinedMacros(); - pinfo.frameworkPaths = allFrameworkPaths; + part->defines = m_toolChain->predefinedMacros(QStringList()); + part->frameworkPaths = allFrameworkPaths; + part->language = CPlusPlus::CppModelManagerInterface::CXX; + pinfo.appendProjectPart(part); + modelManager->updateProjectInfo(pinfo); - modelManager->updateSourceFiles(pinfo.sourceFiles); + modelManager->updateSourceFiles(m_files); } - - modelManager->updateProjectInfo(pinfo); } diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp index 3b0b3117ea5..d6eb593612e 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp @@ -307,18 +307,23 @@ bool CMakeProject::parseCMakeLists() CPlusPlus::CppModelManagerInterface::instance(); if (modelmanager) { CPlusPlus::CppModelManagerInterface::ProjectInfo pinfo = modelmanager->projectInfo(this); - if (pinfo.includePaths != allIncludePaths - || pinfo.sourceFiles != m_files - || pinfo.defines != (activeBC->toolChain() ? activeBC->toolChain()->predefinedMacros() : QByteArray()) - || pinfo.frameworkPaths != allFrameworkPaths) { - pinfo.includePaths = allIncludePaths; + if (pinfo.includePaths() != allIncludePaths + || pinfo.sourceFiles() != m_files + || pinfo.defines() != (activeBC->toolChain() ? activeBC->toolChain()->predefinedMacros(QStringList()) : QByteArray()) + || pinfo.frameworkPaths() != allFrameworkPaths) { + pinfo.clearProjectParts(); + CPlusPlus::CppModelManagerInterface::ProjectPart::Ptr part( + new CPlusPlus::CppModelManagerInterface::ProjectPart); + part->includePaths = allIncludePaths; // TODO we only want C++ files, not all other stuff that might be in the project - pinfo.sourceFiles = m_files; - pinfo.defines = (activeBC->toolChain() ? activeBC->toolChain()->predefinedMacros() : QByteArray()); // TODO this is to simplistic - pinfo.frameworkPaths = allFrameworkPaths; + part->sourceFiles = m_files; + part->defines = (activeBC->toolChain() ? activeBC->toolChain()->predefinedMacros(QStringList()) : QByteArray()); // TODO this is to simplistic + part->frameworkPaths = allFrameworkPaths; + part->language = CPlusPlus::CppModelManagerInterface::CXX; + pinfo.appendProjectPart(part); modelmanager->updateProjectInfo(pinfo); m_codeModelFuture.cancel(); - m_codeModelFuture = modelmanager->updateSourceFiles(pinfo.sourceFiles); + m_codeModelFuture = modelmanager->updateSourceFiles(m_files); } } emit buildTargetsChanged(); diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp index 6505989da90..7833f990995 100644 --- a/src/plugins/cppeditor/cppquickfixes.cpp +++ b/src/plugins/cppeditor/cppquickfixes.cpp @@ -1863,15 +1863,19 @@ public: QList<CppModelManagerInterface::ProjectInfo> projectInfos = modelManager->projectInfos(); bool inProject = false; foreach (const CppModelManagerInterface::ProjectInfo &info, projectInfos) { - if (info.sourceFiles.contains(doc->fileName())) { - inProject = true; - includePaths += info.includePaths; + foreach (CppModelManagerInterface::ProjectPart::Ptr part, info.projectParts()) { + if (part->sourceFiles.contains(doc->fileName())) { + inProject = true; + includePaths += part->includePaths; + } } } if (!inProject) { // better use all include paths than none - foreach (const CppModelManagerInterface::ProjectInfo &info, projectInfos) - includePaths += info.includePaths; + foreach (const CppModelManagerInterface::ProjectInfo &info, projectInfos) { + foreach (CppModelManagerInterface::ProjectPart::Ptr part, info.projectParts()) + includePaths += part->includePaths; + } } // find a include file through the locator diff --git a/src/plugins/cpptools/cppcompletionsupport.cpp b/src/plugins/cpptools/cppcompletionsupport.cpp index 9246708c11f..e68073fcee4 100644 --- a/src/plugins/cpptools/cppcompletionsupport.cpp +++ b/src/plugins/cpptools/cppcompletionsupport.cpp @@ -58,8 +58,8 @@ TextEditor::IAssistInterface *CppCompletionSupport::createAssistInterface(Projec QStringList includePaths; QStringList frameworkPaths; if (project) { - includePaths = modelManager->projectInfo(project).includePaths; - frameworkPaths = modelManager->projectInfo(project).frameworkPaths; + includePaths = modelManager->projectInfo(project).includePaths(); + frameworkPaths = modelManager->projectInfo(project).frameworkPaths(); } return new CppTools::Internal::CppCompletionAssistInterface( document, diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index b3df9853034..2429265fb68 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -90,6 +90,34 @@ #include <iostream> #include <sstream> +namespace CPlusPlus { +uint qHash(const CppModelManagerInterface::ProjectPart &p) +{ + uint h = qHash(p.defines) ^ p.language ^ p.flags; + + foreach (const QString &i, p.includePaths) + h ^= qHash(i); + + foreach (const QString &f, p.frameworkPaths) + h ^= qHash(f); + + return h; +} +bool operator==(const CppModelManagerInterface::ProjectPart &p1, + const CppModelManagerInterface::ProjectPart &p2) +{ + if (p1.defines != p2.defines) + return false; + if (p1.language != p2.language) + return false; + if (p1.flags != p2.flags) + return false; + if (p1.includePaths != p2.includePaths) + return false; + return p1.frameworkPaths == p2.frameworkPaths; +} +} // namespace CPlusPlus + using namespace CppTools; using namespace CppTools::Internal; using namespace CPlusPlus; @@ -733,7 +761,8 @@ QStringList CppModelManager::internalProjectFiles() const while (it.hasNext()) { it.next(); ProjectInfo pinfo = it.value(); - files += pinfo.sourceFiles; + foreach (const ProjectPart::Ptr &part, pinfo.projectParts()) + files += part->sourceFiles; } files.removeDuplicates(); return files; @@ -746,7 +775,8 @@ QStringList CppModelManager::internalIncludePaths() const while (it.hasNext()) { it.next(); ProjectInfo pinfo = it.value(); - includePaths += pinfo.includePaths; + foreach (const ProjectPart::Ptr &part, pinfo.projectParts()) + includePaths += part->includePaths; } includePaths.removeDuplicates(); return includePaths; @@ -759,7 +789,8 @@ QStringList CppModelManager::internalFrameworkPaths() const while (it.hasNext()) { it.next(); ProjectInfo pinfo = it.value(); - frameworkPaths += pinfo.frameworkPaths; + foreach (const ProjectPart::Ptr &part, pinfo.projectParts()) + frameworkPaths += part->frameworkPaths; } frameworkPaths.removeDuplicates(); return frameworkPaths; @@ -772,7 +803,8 @@ QByteArray CppModelManager::internalDefinedMacros() const while (it.hasNext()) { it.next(); ProjectInfo pinfo = it.value(); - macros += pinfo.defines; + foreach (const ProjectPart::Ptr &part, pinfo.projectParts()) + macros += part->defines; } return macros; } @@ -860,13 +892,66 @@ CppModelManager::ProjectInfo CppModelManager::projectInfo(ProjectExplorer::Proje void CppModelManager::updateProjectInfo(const ProjectInfo &pinfo) { +#if 0 + // Tons of debug output... + qDebug()<<"========= CppModelManager::updateProjectInfo ======"; + qDebug()<<" for project:"<< pinfo.project.data()->file()->fileName(); + foreach (const ProjectPart::Ptr &part, pinfo.projectParts) { + qDebug() << "=== part ==="; + qDebug() << "language:" << (part->language == CXX ? "C++" : "ObjC++"); + qDebug() << "compilerflags:" << part->flags; + qDebug() << "precompiled header:" << part->precompiledHeaders; + qDebug() << "defines:" << part->defines; + qDebug() << "includes:" << part->includePaths; + qDebug() << "frameworkPaths:" << part->frameworkPaths; + qDebug() << "sources:" << part->sourceFiles; + qDebug() << ""; + } + + qDebug() << ""; +#endif QMutexLocker locker(&mutex); if (! pinfo.isValid()) return; - m_projects.insert(pinfo.project, pinfo); + ProjectExplorer::Project *project = pinfo.project().data(); + m_projects.insert(project, pinfo); m_dirty = true; + + m_srcToProjectPart.clear(); + + foreach (const ProjectPart::Ptr &projectPart, pinfo.projectParts()) { + foreach (const QString &sourceFile, projectPart->sourceFiles) { + m_srcToProjectPart[sourceFile].append(projectPart); + } + } +} + +QList<CppModelManager::ProjectPart::Ptr> CppModelManager::projectPart(const QString &fileName) const +{ + QList<CppModelManager::ProjectPart::Ptr> parts = m_srcToProjectPart.value(fileName); + if (!parts.isEmpty()) + return parts; + + //### FIXME: This is a DIRTY hack! + if (fileName.endsWith(".h")) { + QString cppFile = fileName.mid(0, fileName.length() - 2) + QLatin1String(".cpp"); + parts = m_srcToProjectPart.value(cppFile); + if (!parts.isEmpty()) + return parts; + } + + DependencyTable table; + table.build(snapshot()); + QStringList deps = table.filesDependingOn(fileName); + foreach (const QString &dep, deps) { + parts = m_srcToProjectPart.value(dep); + if (!parts.isEmpty()) + return parts; + } + + return parts; } QFuture<void> CppModelManager::refreshSourceFiles(const QStringList &sourceFiles) diff --git a/src/plugins/cpptools/cppmodelmanager.h b/src/plugins/cpptools/cppmodelmanager.h index 025e0662311..d56045c2e9e 100644 --- a/src/plugins/cpptools/cppmodelmanager.h +++ b/src/plugins/cpptools/cppmodelmanager.h @@ -83,7 +83,7 @@ class CppPreprocessor; class CppFindReferences; #ifndef ICHECK_BUILD -class CppModelManager : public CPlusPlus::CppModelManagerInterface +class CPPTOOLS_EXPORT CppModelManager : public CPlusPlus::CppModelManagerInterface { Q_OBJECT @@ -99,6 +99,7 @@ public: virtual QList<ProjectInfo> projectInfos() const; virtual ProjectInfo projectInfo(ProjectExplorer::Project *project) const; virtual void updateProjectInfo(const ProjectInfo &pinfo); + virtual QList<ProjectPart::Ptr> projectPart(const QString &fileName) const; virtual CPlusPlus::Snapshot snapshot() const; virtual void GC(); @@ -237,6 +238,8 @@ private: mutable QMutex protectExtraDiagnostics; QHash<QString, QHash<int, QList<CPlusPlus::Document::DiagnosticMessage> > > m_extraDiagnostics; + + QMap<QString, QList<ProjectPart::Ptr> > m_srcToProjectPart; }; #endif diff --git a/src/plugins/cpptools/cpptoolsreuse.cpp b/src/plugins/cpptools/cpptoolsreuse.cpp index 4b7713cf7ea..305e84aded9 100644 --- a/src/plugins/cpptools/cpptoolsreuse.cpp +++ b/src/plugins/cpptools/cpptoolsreuse.cpp @@ -45,18 +45,31 @@ using namespace CPlusPlus; namespace CppTools { -void moveCursorToEndOfIdentifier(QTextCursor *tc) { +static void moveCursorToStartOrEndOfIdentifier(QTextCursor *tc, + QTextCursor::MoveOperation op, + int posDiff = 0) +{ QTextDocument *doc = tc->document(); if (!doc) return; - QChar ch = doc->characterAt(tc->position()); + QChar ch = doc->characterAt(tc->position() - posDiff); while (ch.isLetterOrNumber() || ch == QLatin1Char('_')) { - tc->movePosition(QTextCursor::NextCharacter); - ch = doc->characterAt(tc->position()); + tc->movePosition(op); + ch = doc->characterAt(tc->position() - posDiff); } } +void moveCursorToEndOfIdentifier(QTextCursor *tc) +{ + moveCursorToStartOrEndOfIdentifier(tc, QTextCursor::NextCharacter); +} + +void moveCursorToStartOfIdentifier(QTextCursor *tc) +{ + moveCursorToStartOrEndOfIdentifier(tc, QTextCursor::PreviousCharacter, 1); +} + static bool isOwnershipRAIIName(const QString &name) { static QSet<QString> knownNames; diff --git a/src/plugins/cpptools/cpptoolsreuse.h b/src/plugins/cpptools/cpptoolsreuse.h index 170f601bf57..6bdfb1bec64 100644 --- a/src/plugins/cpptools/cpptoolsreuse.h +++ b/src/plugins/cpptools/cpptoolsreuse.h @@ -45,6 +45,7 @@ class LookupContext; namespace CppTools { void CPPTOOLS_EXPORT moveCursorToEndOfIdentifier(QTextCursor *tc); +void CPPTOOLS_EXPORT moveCursorToStartOfIdentifier(QTextCursor *tc); bool CPPTOOLS_EXPORT isOwnershipRAIIType(CPlusPlus::Symbol *symbol, const CPlusPlus::LookupContext &context); diff --git a/src/plugins/genericprojectmanager/genericproject.cpp b/src/plugins/genericprojectmanager/genericproject.cpp index df458b12840..c1b2adb185e 100644 --- a/src/plugins/genericprojectmanager/genericproject.cpp +++ b/src/plugins/genericprojectmanager/genericproject.cpp @@ -257,30 +257,33 @@ void GenericProject::refresh(RefreshOptions options) if (modelManager) { CPlusPlus::CppModelManagerInterface::ProjectInfo pinfo = modelManager->projectInfo(this); + pinfo.clearProjectParts(); + CPlusPlus::CppModelManagerInterface::ProjectPart::Ptr part( + new CPlusPlus::CppModelManagerInterface::ProjectPart); if (m_toolChain) { - pinfo.defines = m_toolChain->predefinedMacros(); - pinfo.defines += '\n'; + part->defines = m_toolChain->predefinedMacros(QStringList()); + part->defines += '\n'; foreach (const HeaderPath &headerPath, m_toolChain->systemHeaderPaths()) { if (headerPath.kind() == HeaderPath::FrameworkHeaderPath) - pinfo.frameworkPaths.append(headerPath.path()); + part->frameworkPaths.append(headerPath.path()); else - pinfo.includePaths.append(headerPath.path()); + part->includePaths.append(headerPath.path()); } } - pinfo.includePaths += allIncludePaths(); - pinfo.defines += m_defines; + part->includePaths += allIncludePaths(); + part->defines += m_defines; // ### add _defines. - pinfo.sourceFiles = files(); - pinfo.sourceFiles += generated(); + part->sourceFiles = files(); + part->sourceFiles += generated(); QStringList filesToUpdate; if (options & Configuration) { - filesToUpdate = pinfo.sourceFiles; + filesToUpdate = part->sourceFiles; filesToUpdate.append(QLatin1String("<configuration>")); // XXX don't hardcode configuration file name // Full update, if there's a code model update, cancel it m_codeModelFuture.cancel(); @@ -291,6 +294,8 @@ void GenericProject::refresh(RefreshOptions options) filesToUpdate.append(newFileList.toList()); } + pinfo.appendProjectPart(part); + modelManager->updateProjectInfo(pinfo); m_codeModelFuture = modelManager->updateSourceFiles(filesToUpdate); } diff --git a/src/plugins/projectexplorer/abstractmsvctoolchain.cpp b/src/plugins/projectexplorer/abstractmsvctoolchain.cpp index 663d4a91d2f..136bef3069c 100644 --- a/src/plugins/projectexplorer/abstractmsvctoolchain.cpp +++ b/src/plugins/projectexplorer/abstractmsvctoolchain.cpp @@ -85,16 +85,22 @@ bool AbstractMsvcToolChain::isValid() const return !m_vcvarsBat.isEmpty(); } -QByteArray AbstractMsvcToolChain::predefinedMacros() const +QByteArray AbstractMsvcToolChain::predefinedMacros(const QStringList &cxxflags) const { if (m_predefinedMacros.isEmpty()) { Utils::Environment env(m_lastEnvironment); addToEnvironment(env); - m_predefinedMacros = msvcPredefinedMacros(env); + m_predefinedMacros = msvcPredefinedMacros(cxxflags, env); } return m_predefinedMacros; } +ToolChain::CompilerFlags AbstractMsvcToolChain::compilerFlags(const QStringList &cxxflags) const +{ + Q_UNUSED(cxxflags); + return NO_FLAGS; +} + QList<HeaderPath> AbstractMsvcToolChain::systemHeaderPaths() const { if (m_headerPaths.isEmpty()) { @@ -118,7 +124,6 @@ void AbstractMsvcToolChain::addToEnvironment(Utils::Environment &env) const env = m_resultEnvironment; } - QString AbstractMsvcToolChain::makeCommand() const { if (ProjectExplorerPlugin::instance()->projectExplorerSettings().useJom) { @@ -158,9 +163,12 @@ bool AbstractMsvcToolChain::canClone() const return true; } -QByteArray AbstractMsvcToolChain::msvcPredefinedMacros(const Utils::Environment& env) const +QByteArray AbstractMsvcToolChain::msvcPredefinedMacros(const QStringList cxxflags, + const Utils::Environment& env) const { + Q_UNUSED(cxxflags); Q_UNUSED(env); + QByteArray predefinedMacros = "#define __MSVCRT__\n" "#define __w64\n" "#define __int64 long long\n" diff --git a/src/plugins/projectexplorer/abstractmsvctoolchain.h b/src/plugins/projectexplorer/abstractmsvctoolchain.h index 2625b4ff838..519785880c0 100644 --- a/src/plugins/projectexplorer/abstractmsvctoolchain.h +++ b/src/plugins/projectexplorer/abstractmsvctoolchain.h @@ -50,11 +50,12 @@ public: Abi targetAbi() const; bool isValid() const; - QByteArray predefinedMacros() const; + QByteArray predefinedMacros(const QStringList &cxxflags) const; + CompilerFlags compilerFlags(const QStringList &cxxflags) const; QList<HeaderPath> systemHeaderPaths() const; - void addToEnvironment(Utils::Environment &env) const; + QString makeCommand() const; void setDebuggerCommand(const Utils::FileName &d); @@ -71,7 +72,8 @@ public: protected: virtual Utils::Environment readEnvironmentSetting(Utils::Environment& env) const = 0; - virtual QByteArray msvcPredefinedMacros(const Utils::Environment& env) const; + virtual QByteArray msvcPredefinedMacros(const QStringList cxxflags, + const Utils::Environment& env) const; bool generateEnvironmentSettings(Utils::Environment &env, const QString& batchFile, diff --git a/src/plugins/projectexplorer/gcctoolchain.cpp b/src/plugins/projectexplorer/gcctoolchain.cpp index 506b5eb22ba..7cf7be1858a 100644 --- a/src/plugins/projectexplorer/gcctoolchain.cpp +++ b/src/plugins/projectexplorer/gcctoolchain.cpp @@ -95,13 +95,39 @@ static QByteArray runGcc(const Utils::FileName &gcc, const QStringList &argument return cpp.readAllStandardOutput() + '\n' + cpp.readAllStandardError(); } -static QByteArray gccPredefinedMacros(const Utils::FileName &gcc, const QStringList &env) +static QByteArray gccPredefinedMacros(const Utils::FileName &gcc, const QStringList &args, const QStringList &env) { QStringList arguments; arguments << QLatin1String("-xc++") << QLatin1String("-E") - << QLatin1String("-dM") - << QLatin1String("-"); + << QLatin1String("-dM"); + foreach (const QString &a, args) { + if (a == QLatin1String("-m128bit-long-double") || a == QLatin1String("-m32") + || a == QLatin1String("-m3dnow") || a == QLatin1String("-m3dnowa") + || a == QLatin1String("-m64") || a == QLatin1String("-m96bit-long-double") + || a == QLatin1String("-mabm") || a == QLatin1String("-maes") + || a.startsWith(QLatin1String("-march=")) || a == QLatin1String("-mavx") + || a.startsWith(QLatin1String("-masm=")) || a == QLatin1String("-mcx16") + || a == QLatin1String("-mfma") || a == QLatin1String("-mfma4") + || a == QLatin1String("-mlwp") || a == QLatin1String("-mpclmul") + || a == QLatin1String("-mpopcnt") || a == QLatin1String("-msse") + || a == QLatin1String("-msse2") || a == QLatin1String("-msse2avx") + || a == QLatin1String("-msse3") || a == QLatin1String("-msse4") + || a == QLatin1String("-msse4.1") || a == QLatin1String("-msse4.2") + || a == QLatin1String("-msse4a") || a == QLatin1String("-mssse3") + || a.startsWith(QLatin1String("-mtune=")) || a == QLatin1String("-mxop") + || a == QLatin1String("-Os") || a == QLatin1String("-O0") || a == QLatin1String("-O1") + || a == QLatin1String("-O2") || a == QLatin1String("-O3") + || a == QLatin1String("-ffinite-math-only") || a == QLatin1String("-fshort-double") + || a == QLatin1String("-fshort-wchar") || a == QLatin1String("-fsignaling-nans") + || a.startsWith(QLatin1String("-std=")) || a.startsWith(QLatin1String("-specs=")) + || a == QLatin1String("-ansi") + || a.startsWith(QLatin1String("-D")) || a.startsWith(QLatin1String("-U")) + || a == QLatin1String("-undef")) + arguments << a; + } + + arguments << QLatin1String("-"); QByteArray predefinedMacros = runGcc(gcc, arguments, env); #ifdef Q_OS_MAC @@ -295,7 +321,7 @@ GccToolChain::GccToolChain(const QString &id, bool autodetect) : GccToolChain::GccToolChain(const GccToolChain &tc) : ToolChain(tc), - m_predefinedMacros(tc.predefinedMacros()), + m_predefinedMacros(tc.predefinedMacros(QStringList())), m_compilerCommand(tc.compilerCommand()), m_debuggerCommand(tc.debuggerCommand()), m_targetAbi(tc.m_targetAbi), @@ -363,17 +389,24 @@ bool GccToolChain::isValid() const return !m_compilerCommand.isNull(); } -QByteArray GccToolChain::predefinedMacros() const +QByteArray GccToolChain::predefinedMacros(const QStringList &cxxflags) const { if (m_predefinedMacros.isEmpty()) { // Using a clean environment breaks ccache/distcc/etc. Utils::Environment env = Utils::Environment::systemEnvironment(); addToEnvironment(env); - m_predefinedMacros = gccPredefinedMacros(m_compilerCommand, env.toStringList()); + m_predefinedMacros = gccPredefinedMacros(m_compilerCommand, cxxflags, env.toStringList()); } return m_predefinedMacros; } +ProjectExplorer::ToolChain::CompilerFlags GccToolChain::compilerFlags(const QStringList &cxxflags) const +{ + if (cxxflags.contains("-std=c++0x") || cxxflags.contains("-std=gnu++0x")) + return STD_CXX11; + return NO_FLAGS; +} + QList<HeaderPath> GccToolChain::systemHeaderPaths() const { if (m_headerPathes.isEmpty()) { diff --git a/src/plugins/projectexplorer/gcctoolchain.h b/src/plugins/projectexplorer/gcctoolchain.h index 3fd0898fe91..ca9a2c239f4 100644 --- a/src/plugins/projectexplorer/gcctoolchain.h +++ b/src/plugins/projectexplorer/gcctoolchain.h @@ -65,7 +65,9 @@ public: bool isValid() const; - QByteArray predefinedMacros() const; + QByteArray predefinedMacros(const QStringList &cxxflags) const; + CompilerFlags compilerFlags(const QStringList &cxxflags) const; + QList<HeaderPath> systemHeaderPaths() const; void addToEnvironment(Utils::Environment &env) const; QString makeCommand() const; diff --git a/src/plugins/projectexplorer/msvctoolchain.cpp b/src/plugins/projectexplorer/msvctoolchain.cpp index e55cbf25f82..4c09b36ea8f 100644 --- a/src/plugins/projectexplorer/msvctoolchain.cpp +++ b/src/plugins/projectexplorer/msvctoolchain.cpp @@ -143,16 +143,16 @@ static QByteArray msvcCompilationFile() "__cplusplus_cli", "__COUNTER__", "__cplusplus", "_CPPLIB_VER", "_CPPRTTI", "_CPPUNWIND", "_DEBUG", "_DLL", "__FUNCDNAME__", - "__FUNCSIG__","__FUNCTION__","_INTEGRAL_MAX_BITS", - "_M_ALPHA","_M_CEE","_M_CEE_PURE", - "_M_CEE_SAFE","_M_IX86","_M_IA64", - "_M_IX86_FP","_M_MPPC","_M_MRX000", - "_M_PPC","_M_X64","_MANAGED", - "_MFC_VER","_MSC_BUILD", /* "_MSC_EXTENSIONS", */ - "_MSC_FULL_VER","_MSC_VER","__MSVC_RUNTIME_CHECKS", + "__FUNCSIG__", "__FUNCTION__", "_INTEGRAL_MAX_BITS", + "_M_ALPHA", "_M_AAMD64", "_M_CEE", "_M_CEE_PURE", + "_M_CEE_SAFE", "_M_IX86", "_M_IA64", + "_M_IX86_FP", "_M_MPPC", "_M_MRX000", + "_M_PPC", "_M_X64", "_MANAGED", + "_MFC_VER", "_MSC_BUILD", "_MSC_EXTENSIONS", + "_MSC_FULL_VER", "_MSC_VER", "__MSVC_RUNTIME_CHECKS", "_MT", "_NATIVE_WCHAR_T_DEFINED", "_OPENMP", "_VC_NODEFAULTLIB", "_WCHAR_T_DEFINED", "_WIN32", - "_WIN32_WCE", "_WIN64", "_Wp64", "__DATE__", + "_WIN32_WCE", "_WIN64", "_Wp64", "__DATE__", "__TIME__", "__TIMESTAMP__", 0}; QByteArray file = "#define __PPOUT__(x) V##x=x\n\n"; @@ -166,9 +166,35 @@ static QByteArray msvcCompilationFile() } // Run MSVC 'cl' compiler to obtain #defines. -QByteArray MsvcToolChain::msvcPredefinedMacros(const Utils::Environment &env) const -{ - QByteArray predefinedMacros = AbstractMsvcToolChain::msvcPredefinedMacros(env); +QByteArray MsvcToolChain::msvcPredefinedMacros(const QStringList cxxflags, + const Utils::Environment &env) const +{ + QByteArray predefinedMacros = AbstractMsvcToolChain::msvcPredefinedMacros(cxxflags, env); + + QStringList toProcess; + foreach (const QString &arg, cxxflags) { + if (arg.startsWith(QLatin1String("/D"))) { + QString define = arg.mid(2); + int pos = define.indexOf(QLatin1Char('=')); + if (pos < 0) { + predefinedMacros += "#define "; + predefinedMacros += define.toLocal8Bit(); + predefinedMacros += '\n'; + } else { + predefinedMacros += "#define "; + predefinedMacros += define.left(pos).toLocal8Bit(); + predefinedMacros += ' '; + predefinedMacros += define.mid(pos + 1).toLocal8Bit(); + predefinedMacros += '\n'; + } + } else if (arg.startsWith(QLatin1String("/U"))) { + predefinedMacros += "#undef "; + predefinedMacros += arg.mid(2).toLocal8Bit(); + predefinedMacros += '\n'; + } else { + toProcess.append(arg); + } + } Utils::TempFileSaver saver(QDir::tempPath() + QLatin1String("/envtestXXXXXX.cpp")); saver.write(msvcCompilationFile()); @@ -186,7 +212,7 @@ QByteArray MsvcToolChain::msvcPredefinedMacros(const Utils::Environment &env) co return predefinedMacros; } - arguments << QLatin1String("/EP") << QDir::toNativeSeparators(saver.fileName()); + arguments << toProcess << QLatin1String("/EP") << QDir::toNativeSeparators(saver.fileName()); cpp.start(binary, arguments); if (!cpp.waitForStarted()) { qWarning("%s: Cannot start '%s': %s", Q_FUNC_INFO, qPrintable(binary), diff --git a/src/plugins/projectexplorer/msvctoolchain.h b/src/plugins/projectexplorer/msvctoolchain.h index 9f8d20d86a8..d7151e1ba4e 100644 --- a/src/plugins/projectexplorer/msvctoolchain.h +++ b/src/plugins/projectexplorer/msvctoolchain.h @@ -79,7 +79,8 @@ public: protected: Utils::Environment readEnvironmentSetting(Utils::Environment& env) const; - QByteArray msvcPredefinedMacros(const Utils::Environment &env) const; + QByteArray msvcPredefinedMacros(const QStringList cxxflags, + const Utils::Environment &env) const; private: MsvcToolChain(); diff --git a/src/plugins/projectexplorer/toolchain.h b/src/plugins/projectexplorer/toolchain.h index b1df8d43628..e78ee04896e 100644 --- a/src/plugins/projectexplorer/toolchain.h +++ b/src/plugins/projectexplorer/toolchain.h @@ -83,7 +83,13 @@ public: virtual QStringList restrictedToTargets() const; - virtual QByteArray predefinedMacros() const = 0; + virtual QByteArray predefinedMacros(const QStringList &cxxflags) const = 0; + + enum CompilerFlags { + NO_FLAGS = 0, + STD_CXX11 = 1 + }; + virtual CompilerFlags compilerFlags(const QStringList &cxxflags) const = 0; virtual QList<HeaderPath> systemHeaderPaths() const = 0; virtual void addToEnvironment(Utils::Environment &env) const = 0; virtual QString makeCommand() const = 0; diff --git a/src/plugins/qt4projectmanager/qt-s60/gccetoolchain.cpp b/src/plugins/qt4projectmanager/qt-s60/gccetoolchain.cpp index 83332923020..1eb0cec163f 100644 --- a/src/plugins/qt4projectmanager/qt-s60/gccetoolchain.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/gccetoolchain.cpp @@ -94,10 +94,10 @@ QString GcceToolChain::typeDisplayName() const return GcceToolChainFactory::tr("GCCE"); } -QByteArray GcceToolChain::predefinedMacros() const +QByteArray GcceToolChain::predefinedMacros(const QStringList &list) const { if (m_predefinedMacros.isEmpty()) { - ProjectExplorer::GccToolChain::predefinedMacros(); + ProjectExplorer::GccToolChain::predefinedMacros(list); m_predefinedMacros += "\n" "#define __GCCE__\n" "#define __SYMBIAN32__\n"; diff --git a/src/plugins/qt4projectmanager/qt-s60/gccetoolchain.h b/src/plugins/qt4projectmanager/qt-s60/gccetoolchain.h index 7282fb52970..5168b7687e9 100644 --- a/src/plugins/qt4projectmanager/qt-s60/gccetoolchain.h +++ b/src/plugins/qt4projectmanager/qt-s60/gccetoolchain.h @@ -48,7 +48,7 @@ public: QString type() const; QString typeDisplayName() const; - QByteArray predefinedMacros() const; + QByteArray predefinedMacros(const QStringList &list) const; void addToEnvironment(Utils::Environment &env) const; QString makeCommand() const; QString defaultMakeTarget() const; diff --git a/src/plugins/qt4projectmanager/qt-s60/rvcttoolchain.cpp b/src/plugins/qt4projectmanager/qt-s60/rvcttoolchain.cpp index ae09bf3fff9..225b5845b02 100644 --- a/src/plugins/qt4projectmanager/qt-s60/rvcttoolchain.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/rvcttoolchain.cpp @@ -164,8 +164,9 @@ bool RvctToolChain::isValid() const return !m_compilerCommand.isEmpty(); } -QByteArray RvctToolChain::predefinedMacros() const +QByteArray RvctToolChain::predefinedMacros(const QStringList &cxxflags) const { + Q_UNUSED(cxxflags); // see http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0205f/Babbacdb.html (version 2.2) // and http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0491b/BABJFEFG.html (version 4.0) QByteArray ba("#define __ARRAY_OPERATORS\n" @@ -187,6 +188,12 @@ QByteArray RvctToolChain::predefinedMacros() const return ba; } +ProjectExplorer::ToolChain::CompilerFlags RvctToolChain::compilerFlags(const QStringList &cxxflags) const +{ + Q_UNUSED(cxxflags); + return NO_FLAGS; +} + QList<ProjectExplorer::HeaderPath> RvctToolChain::systemHeaderPaths() const { return QList<ProjectExplorer::HeaderPath>() diff --git a/src/plugins/qt4projectmanager/qt-s60/rvcttoolchain.h b/src/plugins/qt4projectmanager/qt-s60/rvcttoolchain.h index af2f3ab5a9c..36e9df44d35 100644 --- a/src/plugins/qt4projectmanager/qt-s60/rvcttoolchain.h +++ b/src/plugins/qt4projectmanager/qt-s60/rvcttoolchain.h @@ -89,7 +89,8 @@ public: bool isValid() const; - QByteArray predefinedMacros() const; + QByteArray predefinedMacros(const QStringList &cxxflags) const; + ProjectExplorer::ToolChain::CompilerFlags compilerFlags(const QStringList &cxxflags) const; QList<ProjectExplorer::HeaderPath> systemHeaderPaths() const; void addToEnvironment(Utils::Environment &env) const; QString makeCommand() const; diff --git a/src/plugins/qt4projectmanager/qt-s60/winscwtoolchain.cpp b/src/plugins/qt4projectmanager/qt-s60/winscwtoolchain.cpp index 533f078ca78..92edcb67fc8 100644 --- a/src/plugins/qt4projectmanager/qt-s60/winscwtoolchain.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/winscwtoolchain.cpp @@ -166,11 +166,18 @@ bool WinscwToolChain::isValid() const return fi.exists() && fi.isExecutable(); } -QByteArray WinscwToolChain::predefinedMacros() const +QByteArray WinscwToolChain::predefinedMacros(const QStringList &cxxflags) const { + Q_UNUSED(cxxflags); return QByteArray("#define __SYMBIAN32__\n"); } +ProjectExplorer::ToolChain::CompilerFlags WinscwToolChain::compilerFlags(const QStringList &cxxflags) const +{ + Q_UNUSED(cxxflags); + return NO_FLAGS; +} + QList<ProjectExplorer::HeaderPath> WinscwToolChain::systemHeaderPaths() const { QList<ProjectExplorer::HeaderPath> result; diff --git a/src/plugins/qt4projectmanager/qt-s60/winscwtoolchain.h b/src/plugins/qt4projectmanager/qt-s60/winscwtoolchain.h index 22d580332d0..070eeed0ede 100644 --- a/src/plugins/qt4projectmanager/qt-s60/winscwtoolchain.h +++ b/src/plugins/qt4projectmanager/qt-s60/winscwtoolchain.h @@ -59,7 +59,8 @@ public: bool isValid() const; - QByteArray predefinedMacros() const; + QByteArray predefinedMacros(const QStringList &list) const; + ProjectExplorer::ToolChain::CompilerFlags compilerFlags(const QStringList &cxxflags) const; QList<ProjectExplorer::HeaderPath> systemHeaderPaths() const; void addToEnvironment(Utils::Environment &env) const; QString makeCommand() const; diff --git a/src/plugins/qt4projectmanager/qt4nodes.cpp b/src/plugins/qt4projectmanager/qt4nodes.cpp index 89fa1a6311d..93b1a5596e0 100644 --- a/src/plugins/qt4projectmanager/qt4nodes.cpp +++ b/src/plugins/qt4projectmanager/qt4nodes.cpp @@ -1410,6 +1410,27 @@ QStringList Qt4ProFileNode::symbianCapabilities() const return result; } +QByteArray Qt4ProFileNode::cxxDefines() const +{ + QByteArray result; + foreach (const QString &def, variableValue(DefinesVar)) { + result += "#define "; + const int index = def.indexOf(QLatin1Char('=')); + if (index == -1) { + result += def.toLatin1(); + result += " 1\n"; + } else { + const QString name = def.left(index); + const QString value = def.mid(index + 1); + result += name.toLatin1(); + result += ' '; + result += value.toLocal8Bit(); + result += '\n'; + } + } + return result; +} + bool Qt4ProFileNode::isDeployable() const { return m_isDeployable; @@ -1829,6 +1850,15 @@ void Qt4ProFileNode::applyEvaluate(EvalResult evalResult, bool async) newVarValues[DefinesVar] = m_readerExact->values(QLatin1String("DEFINES")); newVarValues[IncludePathVar] = includePaths(m_readerExact); + newVarValues[CppFlagsVar] = m_readerExact->values("QMAKE_CXXFLAGS"); + newVarValues[CppSourceVar] = m_readerExact->absoluteFileValues(QLatin1String("SOURCES"), + m_projectDir, + QStringList() << m_projectDir, + 0); + newVarValues[ObjCSourceVar] = m_readerExact->absoluteFileValues(QLatin1String("OBJECTIVE_SOURCES"), + m_projectDir, + QStringList() << m_projectDir, + 0); newVarValues[UiDirVar] = QStringList() << uiDirPath(m_readerExact); newVarValues[MocDirVar] = QStringList() << mocDirPath(m_readerExact); newVarValues[PkgConfigVar] = m_readerExact->values(QLatin1String("PKGCONFIG")); diff --git a/src/plugins/qt4projectmanager/qt4nodes.h b/src/plugins/qt4projectmanager/qt4nodes.h index bb5ade1f778..d2474f035ac 100644 --- a/src/plugins/qt4projectmanager/qt4nodes.h +++ b/src/plugins/qt4projectmanager/qt4nodes.h @@ -82,6 +82,9 @@ enum Qt4ProjectType { enum Qt4Variable { DefinesVar = 1, IncludePathVar, + CppFlagsVar, + CppSourceVar, + ObjCSourceVar, UiDirVar, MocDirVar, PkgConfigVar, @@ -354,6 +357,7 @@ public: QString makefile() const; QStringList symbianCapabilities() const; + QByteArray cxxDefines() const; bool isDeployable() const; QString resolvedMkspecPath() const; diff --git a/src/plugins/qt4projectmanager/qt4project.cpp b/src/plugins/qt4projectmanager/qt4project.cpp index c1abc4b0c13..0f57d950979 100644 --- a/src/plugins/qt4projectmanager/qt4project.cpp +++ b/src/plugins/qt4projectmanager/qt4project.cpp @@ -469,6 +469,8 @@ void Qt4Project::updateCodeModels() void Qt4Project::updateCppCodeModel() { + typedef CPlusPlus::CppModelManagerInterface::ProjectPart ProjectPart; + QtSupport::BaseQtVersion *qtVersion = 0; ToolChain *tc = 0; if (Qt4BaseTarget *target = activeTarget()) { @@ -485,115 +487,78 @@ void Qt4Project::updateCppCodeModel() if (!modelmanager) return; - // Collect global headers/defines - QStringList predefinedIncludePaths; - QStringList predefinedFrameworkPaths; - QByteArray predefinedMacros; - - QString qtFrameworkPath; - if (qtVersion) - qtFrameworkPath = qtVersion->frameworkInstallPath(); - if (!qtFrameworkPath.isEmpty()) - predefinedFrameworkPaths.append(qtFrameworkPath); - - if (tc) { - predefinedMacros = tc->predefinedMacros(); - - QList<HeaderPath> headers = tc->systemHeaderPaths(); - if (qtVersion) - headers.append(qtVersion->systemHeaderPathes()); - foreach (const HeaderPath &headerPath, headers) { - if (headerPath.kind() == HeaderPath::FrameworkHeaderPath) - predefinedFrameworkPaths.append(headerPath.path()); - else - predefinedIncludePaths.append(headerPath.path()); - } - } - FindQt4ProFiles findQt4ProFiles; QList<Qt4ProFileNode *> proFiles = findQt4ProFiles(rootProjectNode()); - QByteArray allDefinedMacros = predefinedMacros; - QStringList allIncludePaths; - QStringList allFrameworkPaths = predefinedFrameworkPaths; - QStringList allPrecompileHeaders; - // Collect per .pro file information + CPlusPlus::CppModelManagerInterface::ProjectInfo pinfo = modelmanager->projectInfo(this); + pinfo.clearProjectParts(); + ProjectPart::QtVersion qtVersionForPart = ProjectPart::NoQt; + if (qtVersion) { + if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0)) + qtVersionForPart = ProjectPart::Qt4; + else + qtVersionForPart = ProjectPart::Qt5; + } + + QStringList allFiles; foreach (Qt4ProFileNode *pro, proFiles) { - allPrecompileHeaders.append(pro->variableValue(PrecompiledHeaderVar)); + ProjectPart::Ptr part(new ProjectPart); + part->qtVersion = qtVersionForPart; - // Add custom defines + // part->defines + if (tc) + part->defines = tc->predefinedMacros(pro->variableValue(CppFlagsVar)); + part->defines += pro->cxxDefines(); - foreach (const QString &def, pro->variableValue(DefinesVar)) { - allDefinedMacros += "#define "; - const int index = def.indexOf(QLatin1Char('=')); - if (index == -1) { - allDefinedMacros += def.toLatin1(); - allDefinedMacros += " 1\n"; - } else { - const QString name = def.left(index); - const QString value = def.mid(index + 1); - allDefinedMacros += name.toLatin1(); - allDefinedMacros += ' '; - allDefinedMacros += value.toLocal8Bit(); - allDefinedMacros += '\n'; - } - } + // part->includePaths + part->includePaths.append(pro->variableValue(IncludePathVar)); - const QStringList proIncludePaths = pro->variableValue(IncludePathVar); - foreach (const QString &includePath, proIncludePaths) { - if (!allIncludePaths.contains(includePath)) - allIncludePaths.append(includePath); + QList<HeaderPath> headers; + if (tc) + headers = tc->systemHeaderPaths(); // todo pass cxxflags? + if (qtVersion) { + headers.append(qtVersion->systemHeaderPathes()); } - } - - // Add mkspec directory - if (rootQt4ProjectNode()) - allIncludePaths.append(rootQt4ProjectNode()->resolvedMkspecPath()); - else if (qtVersion) - allIncludePaths.append(qtVersion->mkspecPath().toString()); - allIncludePaths.append(predefinedIncludePaths); + foreach (const HeaderPath &headerPath, headers) { + if (headerPath.kind() == HeaderPath::FrameworkHeaderPath) + part->frameworkPaths.append(headerPath.path()); + else + part->includePaths.append(headerPath.path()); + } - QStringList files; - files += m_projectFiles->files[HeaderType]; - files += m_projectFiles->generatedFiles[HeaderType]; - files += m_projectFiles->files[SourceType]; - files += m_projectFiles->generatedFiles[SourceType]; + if (qtVersion) { + if (!qtVersion->frameworkInstallPath().isEmpty()) + part->frameworkPaths.append(qtVersion->frameworkInstallPath()); + part->includePaths.append(qtVersion->mkspecPath().toString()); + } - CPlusPlus::CppModelManagerInterface::ProjectInfo pinfo = modelmanager->projectInfo(this); + // part->precompiledHeaders + part->precompiledHeaders.append(pro->variableValue(PrecompiledHeaderVar)); - //qDebug()<<"Using precompiled header"<<allPrecompileHeaders; + // part->language + part->language = CPlusPlus::CppModelManagerInterface::CXX; + // part->flags + if (tc) + part->flags = tc->compilerFlags(pro->variableValue(CppFlagsVar)); - bool fileList = equalFileList(pinfo.sourceFiles, files); + part->sourceFiles = pro->variableValue(CppSourceVar); + pinfo.appendProjectPart(part); - if (pinfo.defines == allDefinedMacros - && pinfo.includePaths == allIncludePaths - && pinfo.frameworkPaths == allFrameworkPaths - && fileList - && pinfo.precompiledHeaders == allPrecompileHeaders - && !m_codeModelCanceled) { - // Nothing to update... - } else { - pinfo.sourceFiles.clear(); - if (pinfo.defines != allDefinedMacros - || pinfo.includePaths != allIncludePaths - || pinfo.frameworkPaths != allFrameworkPaths - || pinfo.precompiledHeaders != allPrecompileHeaders) - { - pinfo.sourceFiles.append(QLatin1String("<configuration>")); - } + allFiles += part->sourceFiles; - //pinfo.defines = predefinedMacros; - pinfo.defines = allDefinedMacros; - pinfo.includePaths = allIncludePaths; - pinfo.frameworkPaths = allFrameworkPaths; - pinfo.sourceFiles += files; - pinfo.precompiledHeaders = allPrecompileHeaders; + part = ProjectPart::Ptr(new ProjectPart); + // todo objc code? + part->language = CPlusPlus::CppModelManagerInterface::OBJC; + part->sourceFiles = pro->variableValue(ObjCSourceVar); + if (!part->sourceFiles.isEmpty()) + pinfo.appendProjectPart(part); - modelmanager->updateProjectInfo(pinfo); - m_codeModelFuture = modelmanager->updateSourceFiles(pinfo.sourceFiles); - m_codeModelCanceled = false; + allFiles += part->sourceFiles; } + + modelmanager->updateProjectInfo(pinfo); + m_codeModelFuture = modelmanager->updateSourceFiles(allFiles); } void Qt4Project::updateQmlJSCodeModel() diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp index b94eb85a82f..9f8442c39d7 100644 --- a/src/plugins/texteditor/basetexteditor.cpp +++ b/src/plugins/texteditor/basetexteditor.cpp @@ -663,7 +663,7 @@ void BaseTextEditorWidget::setChangeSet(const Utils::ChangeSet &changeSet) } } -Core::IFile *BaseTextEditorWidget::file() +Core::IFile *BaseTextEditorWidget::file() const { return d->m_document; } diff --git a/src/plugins/texteditor/basetexteditor.h b/src/plugins/texteditor/basetexteditor.h index b19dc71c12b..f4ca0a3f06c 100644 --- a/src/plugins/texteditor/basetexteditor.h +++ b/src/plugins/texteditor/basetexteditor.h @@ -141,7 +141,7 @@ public: void setChangeSet(const Utils::ChangeSet &changeSet); // EditorInterface - Core::IFile * file(); + Core::IFile * file() const; bool createNew(const QString &contents); virtual bool open(QString *errorString, const QString &fileName, const QString &realFileName); QByteArray saveState() const; diff --git a/src/plugins/texteditor/codeassist/genericproposal.h b/src/plugins/texteditor/codeassist/genericproposal.h index 01ced74d6b2..103def04dff 100644 --- a/src/plugins/texteditor/codeassist/genericproposal.h +++ b/src/plugins/texteditor/codeassist/genericproposal.h @@ -43,7 +43,7 @@ class TEXTEDITOR_EXPORT GenericProposal : public IAssistProposal { public: GenericProposal(int cursorPos, IGenericProposalModel *model); - ~GenericProposal(); + virtual ~GenericProposal(); virtual bool isFragile() const; virtual int basePosition() const; diff --git a/src/plugins/texteditor/semantichighlighter.h b/src/plugins/texteditor/semantichighlighter.h index 62e80e27ccb..726f282d21d 100644 --- a/src/plugins/texteditor/semantichighlighter.h +++ b/src/plugins/texteditor/semantichighlighter.h @@ -58,6 +58,12 @@ public: unsigned length; int kind; + bool isValid() const + { return line != 0; } + + bool isInvalid() const + { return line == 0; } + Result() : line(0), column(0), length(0), kind(-1) {} Result(unsigned line, unsigned column, unsigned length, int kind) -- GitLab