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