From 75c36c9bb5b81d2203a9dd5c7595233b6bdd3b86 Mon Sep 17 00:00:00 2001
From: Tobias Hunger <tobias.hunger@digia.com>
Date: Tue, 20 Nov 2012 17:30:05 +0100
Subject: [PATCH] Gcc: Support -stdlib=whatever arguments for the code model

Switching the stdlib implementation is possible with clang and results
in different include pathes being used (and potentially different defines).

Change-Id: I9c856256f51ceded9dc7892c1dde2bcc8c1b024c
Reviewed-by: Daniel Teske <daniel.teske@digia.com>
---
 .../autotoolsprojectmanager/autotoolsproject.cpp  |  7 +++++--
 src/plugins/cmakeprojectmanager/cmakeproject.cpp  |  6 ++++--
 .../genericprojectmanager/genericproject.cpp      |  5 +++--
 .../projectexplorer/abstractmsvctoolchain.cpp     |  3 ++-
 .../projectexplorer/abstractmsvctoolchain.h       |  2 +-
 src/plugins/projectexplorer/gcctoolchain.cpp      | 15 +++++++++++----
 src/plugins/projectexplorer/gcctoolchain.h        |  4 ++--
 src/plugins/projectexplorer/toolchain.h           |  3 ++-
 src/plugins/qt4projectmanager/qt4project.cpp      |  6 ++++--
 9 files changed, 34 insertions(+), 17 deletions(-)

diff --git a/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp b/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp
index c4662e74596..1080dc5636a 100644
--- a/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp
+++ b/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp
@@ -408,18 +408,21 @@ void AutotoolsProject::updateCppCodeModel()
     QStringList allFrameworkPaths;
     QByteArray macros;
 
+    QStringList cxxflags; // FIXME: Autotools should be able to do better than this!
+
     if (activeTarget()) {
         ProjectExplorer::Kit *k = activeTarget()->kit();
         ToolChain *tc = ProjectExplorer::ToolChainKitInformation::toolChain(k);
         if (tc) {
-            const QList<HeaderPath> allHeaderPaths = tc->systemHeaderPaths(SysRootKitInformation::sysRoot(k));
+            const QList<HeaderPath> allHeaderPaths = tc->systemHeaderPaths(cxxflags,
+                                                                           SysRootKitInformation::sysRoot(k));
             foreach (const HeaderPath &headerPath, allHeaderPaths) {
                 if (headerPath.kind() == HeaderPath::FrameworkHeaderPath)
                     allFrameworkPaths.append(headerPath.path());
                 else
                     allIncludePaths.append(headerPath.path());
             }
-            macros = tc->predefinedMacros(QStringList());
+            macros = tc->predefinedMacros(cxxflags);
             macros += '\n';
         }
     }
diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp
index b07aab805b7..1a6cf70b9da 100644
--- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp
@@ -303,13 +303,15 @@ bool CMakeProject::parseCMakeLists()
     allIncludePaths.append(projectDirectory());
     allIncludePaths.append(cbpparser.includeFiles());
 
+    QStringList cxxflags; // FIXME: We should do better than this!
+
     QByteArray allDefines;
-    allDefines.append(tc->predefinedMacros(QStringList()));
+    allDefines.append(tc->predefinedMacros(cxxflags));
     allDefines.append(cbpparser.defines());
 
     QStringList allFrameworkPaths;
     QList<ProjectExplorer::HeaderPath> allHeaderPaths;
-    allHeaderPaths = tc->systemHeaderPaths(SysRootKitInformation::sysRoot(k));
+    allHeaderPaths = tc->systemHeaderPaths(cxxflags, SysRootKitInformation::sysRoot(k));
     foreach (const ProjectExplorer::HeaderPath &headerPath, allHeaderPaths) {
         if (headerPath.kind() == ProjectExplorer::HeaderPath::FrameworkHeaderPath)
             allFrameworkPaths.append(headerPath.path());
diff --git a/src/plugins/genericprojectmanager/genericproject.cpp b/src/plugins/genericprojectmanager/genericproject.cpp
index 9a9dc3c6e15..16e8e8785f5 100644
--- a/src/plugins/genericprojectmanager/genericproject.cpp
+++ b/src/plugins/genericprojectmanager/genericproject.cpp
@@ -250,10 +250,11 @@ void GenericProject::refresh(RefreshOptions options)
         Kit *k = activeTarget() ? activeTarget()->kit() : KitManager::instance()->defaultKit();
         ToolChain *tc = k ? ToolChainKitInformation::toolChain(k) : 0;
         if (tc) {
-            part->defines = tc->predefinedMacros(QStringList());
+            QStringList cxxflags; // FIXME: Can we do better?
+            part->defines = tc->predefinedMacros(cxxflags);
             part->defines += '\n';
 
-            foreach (const HeaderPath &headerPath, tc->systemHeaderPaths(SysRootKitInformation::sysRoot(k))) {
+            foreach (const HeaderPath &headerPath, tc->systemHeaderPaths(cxxflags, SysRootKitInformation::sysRoot(k))) {
                 if (headerPath.kind() == HeaderPath::FrameworkHeaderPath)
                     part->frameworkPaths.append(headerPath.path());
                 else
diff --git a/src/plugins/projectexplorer/abstractmsvctoolchain.cpp b/src/plugins/projectexplorer/abstractmsvctoolchain.cpp
index 29d9fb7935a..7e38bae9436 100644
--- a/src/plugins/projectexplorer/abstractmsvctoolchain.cpp
+++ b/src/plugins/projectexplorer/abstractmsvctoolchain.cpp
@@ -105,8 +105,9 @@ ToolChain::CompilerFlags AbstractMsvcToolChain::compilerFlags(const QStringList
     }
 }
 
-QList<HeaderPath> AbstractMsvcToolChain::systemHeaderPaths(const Utils::FileName &sysRoot) const
+QList<HeaderPath> AbstractMsvcToolChain::systemHeaderPaths(const QStringList &cxxflags, const Utils::FileName &sysRoot) const
 {
+    Q_UNUSED(cxxflags);
     Q_UNUSED(sysRoot);
     if (m_headerPaths.isEmpty()) {
         Utils::Environment env(m_lastEnvironment);
diff --git a/src/plugins/projectexplorer/abstractmsvctoolchain.h b/src/plugins/projectexplorer/abstractmsvctoolchain.h
index 44ee1b4af15..4c364227342 100644
--- a/src/plugins/projectexplorer/abstractmsvctoolchain.h
+++ b/src/plugins/projectexplorer/abstractmsvctoolchain.h
@@ -50,7 +50,7 @@ public:
 
     QByteArray predefinedMacros(const QStringList &cxxflags) const;
     CompilerFlags compilerFlags(const QStringList &cxxflags) const;
-    QList<HeaderPath> systemHeaderPaths(const Utils::FileName &sysRoot) const;
+    QList<HeaderPath> systemHeaderPaths(const QStringList &cxxflags, const Utils::FileName &sysRoot) const;
     void addToEnvironment(Utils::Environment &env) const;
 
     QString makeCommand(const Utils::Environment &environment) const;
diff --git a/src/plugins/projectexplorer/gcctoolchain.cpp b/src/plugins/projectexplorer/gcctoolchain.cpp
index 765720f84b3..ceabb4ba172 100644
--- a/src/plugins/projectexplorer/gcctoolchain.cpp
+++ b/src/plugins/projectexplorer/gcctoolchain.cpp
@@ -122,7 +122,8 @@ static QByteArray gccPredefinedMacros(const FileName &gcc, const QStringList &ar
                 || 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.startsWith(QLatin1String("-std=")) || a.startsWith(QLatin1String("-stdlib="))
+                || a.startsWith(QLatin1String("-specs="))
                 || a == QLatin1String("-ansi")
                 || a.startsWith(QLatin1String("-D")) || a.startsWith(QLatin1String("-U"))
                 || a == QLatin1String("-undef"))
@@ -148,12 +149,18 @@ static QByteArray gccPredefinedMacros(const FileName &gcc, const QStringList &ar
     return predefinedMacros;
 }
 
-QList<HeaderPath> GccToolChain::gccHeaderPaths(const FileName &gcc, const QStringList &env, const FileName &sysrootPath)
+QList<HeaderPath> GccToolChain::gccHeaderPaths(const FileName &gcc, const QStringList &args,
+                                               const QStringList &env, const FileName &sysrootPath)
 {
     QList<HeaderPath> systemHeaderPaths;
     QStringList arguments;
     if (!sysrootPath.isEmpty())
         arguments.append(QString::fromLatin1("--sysroot=%1").arg(sysrootPath.toString()));
+    foreach (const QString &a, args) {
+        if (a.startsWith(QLatin1String("-stdlib=")))
+            arguments << a;
+    }
+
     arguments << QLatin1String("-xc++")
               << QLatin1String("-E")
               << QLatin1String("-v")
@@ -393,13 +400,13 @@ ToolChain::CompilerFlags GccToolChain::compilerFlags(const QStringList &cxxflags
     return NO_FLAGS;
 }
 
-QList<HeaderPath> GccToolChain::systemHeaderPaths(const Utils::FileName &sysRoot) const
+QList<HeaderPath> GccToolChain::systemHeaderPaths(const QStringList &cxxflags, const Utils::FileName &sysRoot) const
 {
     if (m_headerPaths.isEmpty()) {
         // Using a clean environment breaks ccache/distcc/etc.
         Environment env = Environment::systemEnvironment();
         addToEnvironment(env);
-        m_headerPaths = gccHeaderPaths(m_compilerCommand, env.toStringList(), sysRoot);
+        m_headerPaths = gccHeaderPaths(m_compilerCommand, cxxflags, env.toStringList(), sysRoot);
     }
     return m_headerPaths;
 }
diff --git a/src/plugins/projectexplorer/gcctoolchain.h b/src/plugins/projectexplorer/gcctoolchain.h
index eca1aa3375b..273f042ee4b 100644
--- a/src/plugins/projectexplorer/gcctoolchain.h
+++ b/src/plugins/projectexplorer/gcctoolchain.h
@@ -63,7 +63,7 @@ public:
     QByteArray predefinedMacros(const QStringList &cxxflags) const;
     CompilerFlags compilerFlags(const QStringList &cxxflags) const;
 
-    QList<HeaderPath> systemHeaderPaths(const Utils::FileName &sysRoot) const;
+    QList<HeaderPath> systemHeaderPaths(const QStringList &cxxflags, const Utils::FileName &sysRoot) const;
     void addToEnvironment(Utils::Environment &env) const;
     QString makeCommand(const Utils::Environment &environment) const;
     QList<Utils::FileName> suggestedMkspecList() const;
@@ -90,7 +90,7 @@ protected:
     virtual QList<Abi> detectSupportedAbis() const;
     virtual QString detectVersion() const;
 
-    static QList<HeaderPath> gccHeaderPaths(const Utils::FileName &gcc, const QStringList &env, const Utils::FileName &sysrootPath);
+    static QList<HeaderPath> gccHeaderPaths(const Utils::FileName &gcc, const QStringList &args, const QStringList &env, const Utils::FileName &sysrootPath);
 
     mutable QByteArray m_predefinedMacros;
 
diff --git a/src/plugins/projectexplorer/toolchain.h b/src/plugins/projectexplorer/toolchain.h
index 5109baa0332..3ea55bbc461 100644
--- a/src/plugins/projectexplorer/toolchain.h
+++ b/src/plugins/projectexplorer/toolchain.h
@@ -87,7 +87,8 @@ public:
         STD_CXX11 = 1
     };
     virtual CompilerFlags compilerFlags(const QStringList &cxxflags) const = 0;
-    virtual QList<HeaderPath> systemHeaderPaths(const Utils::FileName &sysRoot) const = 0;
+    virtual QList<HeaderPath> systemHeaderPaths(const QStringList &cxxflags,
+                                                const Utils::FileName &sysRoot) const = 0;
     virtual void addToEnvironment(Utils::Environment &env) const = 0;
     virtual QString makeCommand(const Utils::Environment &env) const = 0;
 
diff --git a/src/plugins/qt4projectmanager/qt4project.cpp b/src/plugins/qt4projectmanager/qt4project.cpp
index 267826dff47..10e5af5186a 100644
--- a/src/plugins/qt4projectmanager/qt4project.cpp
+++ b/src/plugins/qt4projectmanager/qt4project.cpp
@@ -541,9 +541,11 @@ void Qt4Project::updateCppCodeModel()
         ProjectPart::Ptr part(new ProjectPart);
         part->qtVersion = qtVersionForPart;
 
+        QStringList cxxflags = pro->variableValue(CppFlagsVar);
+
         // part->defines
         if (tc)
-            part->defines = tc->predefinedMacros(pro->variableValue(CppFlagsVar));
+            part->defines = tc->predefinedMacros(cxxflags);
         part->defines += pro->cxxDefines();
 
         // part->includePaths
@@ -551,7 +553,7 @@ void Qt4Project::updateCppCodeModel()
 
         QList<HeaderPath> headers;
         if (tc)
-            headers = tc->systemHeaderPaths(SysRootKitInformation::sysRoot(k)); // todo pass cxxflags?
+            headers = tc->systemHeaderPaths(cxxflags, SysRootKitInformation::sysRoot(k));
         if (qtVersion) {
             headers.append(qtVersion->systemHeaderPathes(k));
         }
-- 
GitLab