From 9bfa6b8e6c3714185b5c2c3068e99d4e29e2b0be Mon Sep 17 00:00:00 2001
From: Aaron Barany <akb825@gmail.com>
Date: Mon, 27 Jun 2016 14:48:08 -0700
Subject: [PATCH 1/1] Added separate toolchain compiler paths for C/C++

Allows separate C and C++ compilers to be set. When using CMake, this will set
both the C and C++ compilers when changing the toolchain.
---
 share/qtcreator/translations/qtcreator_cs.ts       |  16 ++-
 share/qtcreator/translations/qtcreator_de.ts       |  16 ++-
 share/qtcreator/translations/qtcreator_fr.ts       |  18 ++-
 share/qtcreator/translations/qtcreator_ja.ts       |  14 +-
 share/qtcreator/translations/qtcreator_pl.ts       |  18 ++-
 share/qtcreator/translations/qtcreator_ru.ts       |  18 ++-
 share/qtcreator/translations/qtcreator_sl.ts       |  13 +-
 share/qtcreator/translations/qtcreator_uk.ts       |  18 ++-
 share/qtcreator/translations/qtcreator_zh_CN.ts    |   6 +-
 share/qtcreator/translations/qtcreator_zh_TW.ts    |   6 +-
 src/plugins/android/androidtoolchain.cpp           |  10 +-
 .../cmakeprojectmanager/cmakekitinformation.cpp    |  38 +++++-
 src/plugins/ios/iosconfigurations.cpp              |   4 +-
 .../projectexplorer/abstractmsvctoolchain.cpp      |   2 +-
 .../projectexplorer/abstractmsvctoolchain.h        |   2 +-
 src/plugins/projectexplorer/customtoolchain.cpp    |  77 +++++++----
 src/plugins/projectexplorer/customtoolchain.h      |  10 +-
 src/plugins/projectexplorer/gcctoolchain.cpp       | 145 ++++++++++++++-------
 src/plugins/projectexplorer/gcctoolchain.h         |   9 +-
 .../projectexplorer/gcctoolchainfactories.h        |   7 +-
 src/plugins/projectexplorer/kitinformation.cpp     |  14 +-
 src/plugins/projectexplorer/msvctoolchain.h        |   2 +-
 src/plugins/projectexplorer/settingsaccessor.cpp   |   2 +-
 src/plugins/projectexplorer/toolchain.h            |   7 +-
 src/plugins/projectexplorer/toolchainmanager.cpp   |   2 +-
 .../qbsprojectmanager/defaultpropertyprovider.cpp  |   2 +-
 src/plugins/qnx/qnxconfiguration.cpp               |   6 +-
 src/plugins/qnx/qnxtoolchain.cpp                   |   8 +-
 src/tools/sdktool/addkitoperation.cpp              |   1 +
 src/tools/sdktool/addtoolchainoperation.cpp        |  55 +++++---
 src/tools/sdktool/addtoolchainoperation.h          |   7 +-
 src/tools/sdktool/rmkitoperation.cpp               |   1 +
 src/tools/sdktool/rmtoolchainoperation.cpp         |   8 +-
 33 files changed, 388 insertions(+), 174 deletions(-)

diff --git a/share/qtcreator/translations/qtcreator_cs.ts b/share/qtcreator/translations/qtcreator_cs.ts
index 0ef506e..d1685b8 100644
--- a/share/qtcreator/translations/qtcreator_cs.ts
+++ b/share/qtcreator/translations/qtcreator_cs.ts
@@ -40508,8 +40508,12 @@ když bude zavolán mimo git bash.</translation>
 <context>
     <name>ProjectExplorer::Internal::GccToolChainConfigWidget</name>
     <message>
-        <source>&amp;Compiler path:</source>
-        <translation>Cesta k &amp;překladači:</translation>
+        <source>&amp;Compiler path (C):</source>
+        <translation>Cesta k &amp;překladači (C):</translation>
+    </message>
+	<message>
+        <source>Compiler path (C&amp;++):</source>
+        <translation>Cesta k překladači (C&amp;++):</translation>
     </message>
     <message>
         <source>Platform codegen flags:</source>
@@ -64239,8 +64243,12 @@ Commit now?</source>
         <translation>Čárkou oddělený seznam mkspecs.</translation>
     </message>
     <message>
-        <source>&amp;Compiler path:</source>
-        <translation>Cesta k &amp;překladači:</translation>
+        <source>&amp;Compiler path (C):</source>
+        <translation>Cesta k &amp;překladači (C):</translation>
+    </message>
+	<message>
+        <source>Compiler path (C&amp;++):</source>
+        <translation>Cesta k překladači (C&amp;++):</translation>
     </message>
     <message>
         <source>&amp;Make path:</source>
diff --git a/share/qtcreator/translations/qtcreator_de.ts b/share/qtcreator/translations/qtcreator_de.ts
index bce47b7..3d57dbe 100644
--- a/share/qtcreator/translations/qtcreator_de.ts
+++ b/share/qtcreator/translations/qtcreator_de.ts
@@ -15162,8 +15162,12 @@ Lokale Pull-Operationen werden nicht auf den Master-Branch angewandt.</translati
 <context>
     <name>ProjectExplorer::Internal::GccToolChainConfigWidget</name>
     <message>
-        <source>&amp;Compiler path:</source>
-        <translation>&amp;Compiler-Pfad:</translation>
+        <source>&amp;Compiler path (C):</source>
+        <translation>&amp;Compiler-Pfad (C):</translation>
+    </message>
+	<message>
+        <source>Compiler path (C&amp;++):</source>
+        <translation>Compiler-Pfad (C&amp;++):</translation>
     </message>
     <message>
         <source>Platform codegen flags:</source>
@@ -24387,9 +24391,13 @@ Entfernt: %4</translation>
         <source>Comma-separated list of mkspecs.</source>
         <translation>Kommaseparierte Liste der mkspecs.</translation>
     </message>
+	<message>
+        <source>&amp;Compiler path (C):</source>
+        <translation>&amp;Compiler-Pfad (C):</translation>
+    </message>
     <message>
-        <source>&amp;Compiler path:</source>
-        <translation>&amp;Compiler-Pfad:</translation>
+        <source>Compiler path (C&amp;++):</source>
+        <translation>Compiler-Pfad (C&amp;++):</translation>
     </message>
     <message>
         <source>&amp;Make path:</source>
diff --git a/share/qtcreator/translations/qtcreator_fr.ts b/share/qtcreator/translations/qtcreator_fr.ts
index 3469e67..2a6e0e7 100644
--- a/share/qtcreator/translations/qtcreator_fr.ts
+++ b/share/qtcreator/translations/qtcreator_fr.ts
@@ -43496,8 +43496,12 @@ Do you want to retry?</source>
 <context>
     <name>ProjectExplorer::Internal::GccToolChainConfigWidget</name>
     <message>
-        <source>&amp;Compiler path:</source>
-        <translation>Chemin du &amp;compilateur : </translation>
+        <source>&amp;Compiler path (C):</source>
+        <translation>Chemin du &amp;compilateur (C) : </translation>
+    </message>
+	<message>
+        <source>Compiler path (C&amp;++):</source>
+        <translation>Chemin du compilateur (C&amp;++) : </translation>
     </message>
     <message>
         <source>Platform codegen flags:</source>
@@ -68225,9 +68229,13 @@ Distant : %4</translation>
         <source>Comma-separated list of mkspecs.</source>
         <translation>Liste de mkspecs séparés par une virgule.</translation>
     </message>
-    <message>
-        <source>&amp;Compiler path:</source>
-        <translation>Chemin du &amp;compilateur :</translation>
+	<message>
+        <source>&amp;Compiler path (C):</source>
+        <translation>Chemin du &amp;compilateur (C) : </translation>
+    </message>
+	<message>
+        <source>Compiler path (C&amp;++):</source>
+        <translation>Chemin du compilateur (C&amp;++) : </translation>
     </message>
     <message>
         <source>&amp;Make path:</source>
diff --git a/share/qtcreator/translations/qtcreator_ja.ts b/share/qtcreator/translations/qtcreator_ja.ts
index 208d0f4..7839faa 100644
--- a/share/qtcreator/translations/qtcreator_ja.ts
+++ b/share/qtcreator/translations/qtcreator_ja.ts
@@ -20830,9 +20830,13 @@ msysgit が、git bash 外で実行された時に自身のインストール先
         <translation>mkspecs のリストをコンマで区切って記述してください。</translation>
     </message>
     <message>
-        <source>&amp;Compiler path:</source>
+        <source>&amp;Compiler path (C):</source>
         <translation>コンパイラのパス(&amp;C):</translation>
     </message>
+	<message>
+        <source>Compiler path (C&amp;++):</source>
+        <translation>コンパイラのパス(C&amp;++):</translation>
+    </message>
     <message>
         <source>&amp;Make path:</source>
         <translation>make のパス(&amp;M):</translation>
@@ -21503,10 +21507,14 @@ msysgit が、git bash 外で実行された時に自身のインストール先
 </context>
 <context>
     <name>ProjectExplorer::Internal::GccToolChainConfigWidget</name>
-    <message>
-        <source>&amp;Compiler path:</source>
+	<message>
+        <source>&amp;Compiler path (C):</source>
         <translation>コンパイラのパス(&amp;C):</translation>
     </message>
+	<message>
+        <source>Compiler path (C&amp;++):</source>
+        <translation>コンパイラのパス(C&amp;++):</translation>
+    </message>
     <message>
         <source>Platform codegen flags:</source>
         <translation>プラットフォーム用コード生成オプション:</translation>
diff --git a/share/qtcreator/translations/qtcreator_pl.ts b/share/qtcreator/translations/qtcreator_pl.ts
index 28fee93..439eef5 100644
--- a/share/qtcreator/translations/qtcreator_pl.ts
+++ b/share/qtcreator/translations/qtcreator_pl.ts
@@ -16351,8 +16351,12 @@ Ponowić próbę?</translation>
 <context>
     <name>ProjectExplorer::Internal::GccToolChainConfigWidget</name>
     <message>
-        <source>&amp;Compiler path:</source>
-        <translation>Ścieżka do &amp;kompilatora:</translation>
+        <source>&amp;Compiler path (C):</source>
+        <translation>Ścieżka do &amp;kompilatora (C):</translation>
+    </message>
+	<message>
+        <source>Compiler path (C&amp;++):</source>
+        <translation>Ścieżka do kompilatora (C&amp;++):</translation>
     </message>
     <message>
         <source>Platform codegen flags:</source>
@@ -27349,9 +27353,13 @@ Remote: %4</source>
         <source>Comma-separated list of mkspecs.</source>
         <translation>Oddzielona przecinkami lista mkspec&apos;ów.</translation>
     </message>
-    <message>
-        <source>&amp;Compiler path:</source>
-        <translation>Ścieżka do &amp;kompilatora:</translation>
+	<message>
+        <source>&amp;Compiler path (C):</source>
+        <translation>Ścieżka do &amp;kompilatora (C):</translation>
+    </message>
+	<message>
+        <source>Compiler path (C&amp;++):</source>
+        <translation>Ścieżka do kompilatora (C&amp;++):</translation>
     </message>
     <message>
         <source>&amp;Make path:</source>
diff --git a/share/qtcreator/translations/qtcreator_ru.ts b/share/qtcreator/translations/qtcreator_ru.ts
index 84944ea..e18167c 100644
--- a/share/qtcreator/translations/qtcreator_ru.ts
+++ b/share/qtcreator/translations/qtcreator_ru.ts
@@ -23016,8 +23016,12 @@ Ids must begin with a lowercase letter.</source>
         <translation>Разделённый запятыми список mkspec.</translation>
     </message>
     <message>
-        <source>&amp;Compiler path:</source>
-        <translation>Путь к &amp;компилятору:</translation>
+        <source>&amp;Compiler path (C):</source>
+        <translation>Путь к &amp;компилятору (C):</translation>
+    </message>
+	<message>
+        <source>Compiler path (C&amp;++):</source>
+        <translation>Путь к компилятору (C&amp;++):</translation>
     </message>
     <message>
         <source>&amp;Make path:</source>
@@ -23310,9 +23314,13 @@ Ids must begin with a lowercase letter.</source>
 </context>
 <context>
     <name>ProjectExplorer::Internal::GccToolChainConfigWidget</name>
-    <message>
-        <source>&amp;Compiler path:</source>
-        <translation>Путь к &amp;компилятору:</translation>
+	<message>
+        <source>&amp;Compiler path (C):</source>
+        <translation>Путь к &amp;компилятору (C):</translation>
+    </message>
+	<message>
+        <source>Compiler path (C&amp;++):</source>
+        <translation>Путь к компилятору (C&amp;++):</translation>
     </message>
     <message>
         <source>Platform codegen flags:</source>
diff --git a/share/qtcreator/translations/qtcreator_sl.ts b/share/qtcreator/translations/qtcreator_sl.ts
index 8b7d300..3d1f80a 100644
--- a/share/qtcreator/translations/qtcreator_sl.ts
+++ b/share/qtcreator/translations/qtcreator_sl.ts
@@ -30232,8 +30232,13 @@ ključe SSH išče na tem mestu in ne v mapi, kjer je nameščen.</translation>
     <name>ProjectExplorer::Internal::GccToolChainConfigWidget</name>
     <message>
         <location line="+110"/>
-        <source>&amp;Compiler path:</source>
-        <translation>&amp;Pot do prevajalnika:</translation>
+        <source>&amp;Compiler path (C):</source>
+        <translation>&amp;Pot do prevajalnika (C):</translation>
+    </message>
+	<message>
+        <location line="+110"/>
+        <source>Compiler path (C&amp;++):</source>
+        <translation>Pot do prevajalnika (C&amp;++):</translation>
     </message>
     <message>
         <location line="+1"/>
@@ -36872,7 +36877,7 @@ Preverite pravice za dostop do mape.</translation>
     <message>
         <location line="+6"/>
         <source>Timed out after %1s waiting for the process %2 to finish.</source>
-        <translation>Po %1 s čakanja na zaključek procesa %2 je potekel čas.</translation>
+        <translation>Po %1 s čakanja na zaključek procesa %2 je potekel čas.</translation>
     </message>
 </context>
 <context>
@@ -40106,7 +40111,7 @@ Preverite, ali je telefon priključen in ali App TRK teče.</translation>
     </message>
     <message>
         <source>Timed out after %1s waiting for mercurial process to finish.</source>
-        <translation type="obsolete">Po %1 s čakanja na zaključek procesa mercurial je potekel čas.</translation>
+        <translation type="obsolete">Po %1 s čakanja na zaključek procesa mercurial je potekel čas.</translation>
     </message>
 </context>
 <context>
diff --git a/share/qtcreator/translations/qtcreator_uk.ts b/share/qtcreator/translations/qtcreator_uk.ts
index 33c48c0..a0ab7fc 100644
--- a/share/qtcreator/translations/qtcreator_uk.ts
+++ b/share/qtcreator/translations/qtcreator_uk.ts
@@ -17495,8 +17495,12 @@ Reason: %2</source>
 <context>
     <name>ProjectExplorer::Internal::GccToolChainConfigWidget</name>
     <message>
-        <source>&amp;Compiler path:</source>
-        <translation>Шлях до &amp;компілятора:</translation>
+        <source>&amp;Compiler path (C):</source>
+        <translation>Шлях до &amp;компілятора (C):</translation>
+    </message>
+	<message>
+        <source>Compiler path (C&amp;++):</source>
+        <translation>Шлях до компілятора (C&amp;++):</translation>
     </message>
     <message>
         <source>Platform codegen flags:</source>
@@ -38352,9 +38356,13 @@ Remote: %4</source>
         <source>Comma-separated list of mkspecs.</source>
         <translation>Список mkspec, розділених комами.</translation>
     </message>
-    <message>
-        <source>&amp;Compiler path:</source>
-        <translation>Шлях до &amp;компілятора:</translation>
+	<message>
+        <source>&amp;Compiler path (C):</source>
+        <translation>Шлях до &amp;компілятора (C):</translation>
+    </message>
+	<message>
+        <source>Compiler path (C&amp;++):</source>
+        <translation>Шлях до компілятора (C&amp;++):</translation>
     </message>
     <message>
         <source>&amp;Make path:</source>
diff --git a/share/qtcreator/translations/qtcreator_zh_CN.ts b/share/qtcreator/translations/qtcreator_zh_CN.ts
index 1cc26a1..2d22ca7 100644
--- a/share/qtcreator/translations/qtcreator_zh_CN.ts
+++ b/share/qtcreator/translations/qtcreator_zh_CN.ts
@@ -38439,9 +38439,13 @@ Do you want to retry?</source>
 <context>
     <name>ProjectExplorer::Internal::GccToolChainConfigWidget</name>
     <message>
-        <source>&amp;Compiler path:</source>
+        <source>&amp;Compiler path (C):</source>
         <translation>编译器路径(&amp;C):</translation>
     </message>
+	<message>
+        <source>Compiler path (C&amp;++):</source>
+        <translation>编译器路径(C&amp;++):</translation>
+    </message>
     <message>
         <source>&amp;ABI:</source>
         <translation>&amp;ABI:</translation>
diff --git a/share/qtcreator/translations/qtcreator_zh_TW.ts b/share/qtcreator/translations/qtcreator_zh_TW.ts
index bc117ee..77a6976 100644
--- a/share/qtcreator/translations/qtcreator_zh_TW.ts
+++ b/share/qtcreator/translations/qtcreator_zh_TW.ts
@@ -21921,9 +21921,13 @@ Do you want to retry?</source>
 <context>
     <name>ProjectExplorer::Internal::GccToolChainConfigWidget</name>
     <message>
-        <source>&amp;Compiler path:</source>
+        <source>&amp;Compiler path (C):</source>
         <translation>編譯器路徑(&amp;C)：</translation>
     </message>
+	<message>
+        <source>Compiler path (C&amp;++):</source>
+        <translation>編譯器路徑(C&amp;++)：</translation>
+    </message>
     <message>
         <source>&amp;ABI:</source>
         <translation>&amp;ABI：</translation>
diff --git a/src/plugins/android/androidtoolchain.cpp b/src/plugins/android/androidtoolchain.cpp
index 81ce235..f9743b3 100644
--- a/src/plugins/android/androidtoolchain.cpp
+++ b/src/plugins/android/androidtoolchain.cpp
@@ -96,7 +96,8 @@ QString AndroidToolChain::typeDisplayName() const
 bool AndroidToolChain::isValid() const
 {
     return GccToolChain::isValid() && targetAbi().isValid() && !m_ndkToolChainVersion.isEmpty()
-            && compilerCommand().isChildOf(AndroidConfigurations::currentConfig().ndkLocation());
+            && compilerCommand(CLanguage).isChildOf(AndroidConfigurations::currentConfig().ndkLocation())
+            && compilerCommand(CppLanguage).isChildOf(AndroidConfigurations::currentConfig().ndkLocation());
 }
 
 void AndroidToolChain::addToEnvironment(Environment &env) const
@@ -169,7 +170,7 @@ bool AndroidToolChain::fromMap(const QVariantMap &data)
         return false;
 
     if (data.contains(QLatin1String(ANDROID_QT_VERSION_KEY))) {
-        QString command = compilerCommand().toString();
+        QString command = compilerCommand(CppLanguage).toString();
         QString ndkPath = AndroidConfigurations::currentConfig().ndkLocation().toString();
         if (!command.startsWith(ndkPath))
             return false;
@@ -357,7 +358,8 @@ static AndroidToolChain *findToolChain(Utils::FileName &compilerPath, const QLis
     return static_cast<AndroidToolChain *>(
                 Utils::findOrDefault(alreadyKnown, [compilerPath](ToolChain *tc) {
                                                        return tc->typeId() == Constants::ANDROID_TOOLCHAIN_ID
-                                                           && tc->compilerCommand() == compilerPath;
+                                                           && tc->compilerCommand(ToolChain::CLanguage) == compilerPath
+                                                           && tc->compilerCommand(ToolChain::CppLanguage) == compilerPath;
                                                    }));
 }
 
@@ -390,7 +392,7 @@ AndroidToolChainFactory::autodetectToolChainsForNdk(const FileName &ndkPath,
         AndroidToolChain *tc = findToolChain(compilerPath, alreadyKnown);
         if (!tc) {
             tc = new AndroidToolChain(abi, version, ToolChain::AutoDetection);
-            tc->resetToolChain(compilerPath);
+            tc->resetToolChain(compilerPath, compilerPath);
         }
         result.append(tc);
 
diff --git a/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp b/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp
index 0f21fe8..125e5d6 100644
--- a/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp
@@ -273,7 +273,8 @@ KitConfigWidget *CMakeGeneratorKitInformation::createConfigWidget(Kit *k) const
 static const char CONFIGURATION_ID[] = "CMake.ConfigurationKitInformation";
 
 static const char CMAKE_QMAKE_KEY[] = "QT_QMAKE_EXECUTABLE";
-static const char CMAKE_TOOLCHAIN_KEY[] = "CMAKE_CXX_COMPILER";
+static const char CMAKE_C_TOOLCHAIN_KEY[] = "CMAKE_C_COMPILER";
+static const char CMAKE_CXX_TOOLCHAIN_KEY[] = "CMAKE_CXX_COMPILER";
 
 CMakeConfigurationKitInformation::CMakeConfigurationKitInformation()
 {
@@ -324,7 +325,8 @@ CMakeConfig CMakeConfigurationKitInformation::defaultConfiguration(const Kit *k)
     Q_UNUSED(k);
     CMakeConfig config;
     config << CMakeConfigItem(CMAKE_QMAKE_KEY, "%{Qt:qmakeExecutable}");
-    config << CMakeConfigItem(CMAKE_TOOLCHAIN_KEY, "%{Compiler:Executable}");
+    config << CMakeConfigItem(CMAKE_C_TOOLCHAIN_KEY, "%{Compiler:Executable:C}");
+    config << CMakeConfigItem(CMAKE_CXX_TOOLCHAIN_KEY, "%{Compiler:Executable:C++}");
 
     return config;
 }
@@ -347,14 +349,17 @@ QList<Task> CMakeConfigurationKitInformation::validate(const Kit *k) const
     const CMakeConfig config = configuration(k);
 
     QByteArray qmakePath;
-    QByteArray tcPath;
+    QByteArray tcCPath;
+    QByteArray tcCppPath;
     foreach (const CMakeConfigItem &i, config) {
         // Do not use expand(QByteArray) as we can not be sure the input is latin1
         const QByteArray expandedValue = k->macroExpander()->expand(QString::fromUtf8(i.value)).toUtf8();
         if (i.key == CMAKE_QMAKE_KEY)
             qmakePath = expandedValue;
-        else if (i.key == CMAKE_TOOLCHAIN_KEY)
-            tcPath = expandedValue;
+        else if (i.key == CMAKE_C_TOOLCHAIN_KEY)
+            tcCPath = expandedValue;
+        else if (i.key == CMAKE_CXX_TOOLCHAIN_KEY)
+            tcCppPath = expandedValue;
     }
 
     QList<Task> result;
@@ -379,7 +384,26 @@ QList<Task> CMakeConfigurationKitInformation::validate(const Kit *k) const
     }
 
     // Validate Toolchain:
-    if (tcPath.isEmpty()) {
+    if (tcCPath.isEmpty()) {
+        if (tc && tc->isValid()) {
+            result << Task(Task::Warning, tr("CMake configuration has no path to a C compiler set, "
+                                             "even though the kit has a valid tool chain."),
+                           Utils::FileName(), -1, Core::Id(Constants::TASK_CATEGORY_BUILDSYSTEM));
+        }
+    } else {
+        if (!tc || !tc->isValid()) {
+            result << Task(Task::Warning, tr("CMake configuration has a path to a C++ compiler set, "
+                                             "even though the kit has no valid tool chain."),
+                           Utils::FileName(), -1, Core::Id(Constants::TASK_CATEGORY_BUILDSYSTEM));
+        } else if (tcCPath != tc->compilerCommand(ToolChain::CLanguage).toString().toUtf8()) {
+            result << Task(Task::Warning, tr("CMake configuration has a path to a C compiler set, "
+                                             "that does not match up with the compiler path "
+                                             "configured in the tool chain of the kit."),
+                           Utils::FileName(), -1, Core::Id(Constants::TASK_CATEGORY_BUILDSYSTEM));
+        }
+    }
+
+    if (tcCppPath.isEmpty()) {
         if (tc && tc->isValid()) {
             result << Task(Task::Warning, tr("CMake configuration has no path to a C++ compiler set, "
                                              "even though the kit has a valid tool chain."),
@@ -390,7 +414,7 @@ QList<Task> CMakeConfigurationKitInformation::validate(const Kit *k) const
             result << Task(Task::Warning, tr("CMake configuration has a path to a C++ compiler set, "
                                              "even though the kit has no valid tool chain."),
                            Utils::FileName(), -1, Core::Id(Constants::TASK_CATEGORY_BUILDSYSTEM));
-        } else if (tcPath != tc->compilerCommand().toString().toUtf8()) {
+        } else if (tcCppPath != tc->compilerCommand(ToolChain::CppLanguage).toString().toUtf8()) {
             result << Task(Task::Warning, tr("CMake configuration has a path to a C++ compiler set, "
                                              "that does not match up with the compiler path "
                                              "configured in the tool chain of the kit."),
diff --git a/src/plugins/ios/iosconfigurations.cpp b/src/plugins/ios/iosconfigurations.cpp
index 0eb1055..2396570 100644
--- a/src/plugins/ios/iosconfigurations.cpp
+++ b/src/plugins/ios/iosconfigurations.cpp
@@ -118,7 +118,7 @@ static QList<ClangToolChain *> autoDetectedIosToolChains()
 static ClangToolChain *findToolChainForPlatform(const Platform &platform, const QList<ClangToolChain *> &toolChains)
 {
     return Utils::findOrDefault(toolChains, [&platform](ClangToolChain *toolChain) {
-        return platform.compilerPath == toolChain->compilerCommand()
+        return platform.compilerPath == toolChain->compilerCommand(ToolChain::CLanguage)
                && platform.backendFlags == toolChain->platformCodeGenFlags()
                && platform.backendFlags == toolChain->platformLinkerFlags();
     });
@@ -357,7 +357,7 @@ static ClangToolChain *createToolChain(const Platform &platform)
     toolChain->setDisplayName(platform.name);
     toolChain->setPlatformCodeGenFlags(platform.backendFlags);
     toolChain->setPlatformLinkerFlags(platform.backendFlags);
-    toolChain->resetToolChain(platform.compilerPath);
+    toolChain->resetToolChain(platform.compilerPath, platform.compilerPath);
     return toolChain;
 }
 
diff --git a/src/plugins/projectexplorer/abstractmsvctoolchain.cpp b/src/plugins/projectexplorer/abstractmsvctoolchain.cpp
index d7eb341..ad19f6c 100644
--- a/src/plugins/projectexplorer/abstractmsvctoolchain.cpp
+++ b/src/plugins/projectexplorer/abstractmsvctoolchain.cpp
@@ -197,7 +197,7 @@ QString AbstractMsvcToolChain::makeCommand(const Utils::Environment &environment
     return useJom ? jom : nmake;
 }
 
-Utils::FileName AbstractMsvcToolChain::compilerCommand() const
+Utils::FileName AbstractMsvcToolChain::compilerCommand(Language) const
 {
     Utils::Environment env = Utils::Environment::systemEnvironment();
     addToEnvironment(env);
diff --git a/src/plugins/projectexplorer/abstractmsvctoolchain.h b/src/plugins/projectexplorer/abstractmsvctoolchain.h
index be95a36..e87e84f 100644
--- a/src/plugins/projectexplorer/abstractmsvctoolchain.h
+++ b/src/plugins/projectexplorer/abstractmsvctoolchain.h
@@ -53,7 +53,7 @@ public:
     void addToEnvironment(Utils::Environment &env) const override;
 
     QString makeCommand(const Utils::Environment &environment) const override;
-    Utils::FileName compilerCommand() const override;
+    Utils::FileName compilerCommand(Language language) const override;
     IOutputParser *outputParser() const override;
 
     bool canClone() const override;
diff --git a/src/plugins/projectexplorer/customtoolchain.cpp b/src/plugins/projectexplorer/customtoolchain.cpp
index a910450..596852a 100644
--- a/src/plugins/projectexplorer/customtoolchain.cpp
+++ b/src/plugins/projectexplorer/customtoolchain.cpp
@@ -55,7 +55,8 @@ namespace ProjectExplorer {
 // Helpers:
 // --------------------------------------------------------------------------
 
-static const char compilerCommandKeyC[] = "ProjectExplorer.CustomToolChain.CompilerPath";
+static const char compilerCommandKeyCC[] = "ProjectExplorer.CustomToolChain.CompilerPathC";
+static const char compilerCommandKeyCppC[] = "ProjectExplorer.CustomToolChain.CompilerPathCpp";
 static const char makeCommandKeyC[] = "ProjectExplorer.CustomToolChain.MakePath";
 static const char targetAbiKeyC[] = "ProjectExplorer.CustomToolChain.TargetAbi";
 static const char predefinedMacrosKeyC[] = "ProjectExplorer.CustomToolChain.PredefinedMacros";
@@ -180,11 +181,14 @@ QList<HeaderPath> CustomToolChain::systemHeaderPaths(const QStringList &cxxFlags
 
 void CustomToolChain::addToEnvironment(Environment &env) const
 {
-    if (!m_compilerCommand.isEmpty()) {
-        FileName path = m_compilerCommand.parentDir();
-        env.prependOrSetPath(path.toString());
+    if (!m_compilerCommandCpp.isEmpty()) {
+        FileName cppPath = m_compilerCommandCpp.parentDir();
+        env.prependOrSetPath(cppPath.toString());
+        FileName cPath = m_compilerCommandC.parentDir();
+        if (cPath != cppPath)
+            env.prependOrSetPath(cPath.toString());
         FileName makePath = m_makeCommand.parentDir();
-        if (makePath != path)
+        if (makePath != cppPath)
             env.prependOrSetPath(makePath.toString());
     }
 }
@@ -220,17 +224,35 @@ void CustomToolChain::setHeaderPaths(const QStringList &list)
     });
 }
 
-void CustomToolChain::setCompilerCommand(const FileName &path)
-{
-    if (path == m_compilerCommand)
+void CustomToolChain::setCompilerCommand(Language language, const FileName &path)
+{
+    switch (language) {
+    case CLanguage:
+        if (path == m_compilerCommandC)
+            return;
+        m_compilerCommandC = path;
+        break;
+    case CppLanguage:
+        if (path == m_compilerCommandCpp)
+            return;
+        m_compilerCommandCpp = path;
+        break;
+    default:
         return;
-    m_compilerCommand = path;
+    }
     toolChainUpdated();
 }
 
-FileName CustomToolChain::compilerCommand() const
+FileName CustomToolChain::compilerCommand(Language language) const
 {
-    return m_compilerCommand;
+    switch (language) {
+    case CLanguage:
+        return m_compilerCommandC;
+    case CppLanguage:
+        return m_compilerCommandCpp;
+    default:
+        return FileName();
+    }
 }
 
 void CustomToolChain::setMakeCommand(const FileName &path)
@@ -282,7 +304,8 @@ ToolChain *CustomToolChain::clone() const
 QVariantMap CustomToolChain::toMap() const
 {
     QVariantMap data = ToolChain::toMap();
-    data.insert(QLatin1String(compilerCommandKeyC), m_compilerCommand.toString());
+    data.insert(QLatin1String(compilerCommandKeyCC), m_compilerCommandC.toString());
+    data.insert(QLatin1String(compilerCommandKeyCppC), m_compilerCommandCpp.toString());
     data.insert(QLatin1String(makeCommandKeyC), m_makeCommand.toString());
     data.insert(QLatin1String(targetAbiKeyC), m_targetAbi.toString());
     data.insert(QLatin1String(predefinedMacrosKeyC), m_predefinedMacros);
@@ -311,7 +334,8 @@ bool CustomToolChain::fromMap(const QVariantMap &data)
     if (!ToolChain::fromMap(data))
         return false;
 
-    m_compilerCommand = FileName::fromString(data.value(QLatin1String(compilerCommandKeyC)).toString());
+    m_compilerCommandC = FileName::fromString(data.value(QLatin1String(compilerCommandKeyCC)).toString());
+    m_compilerCommandCpp = FileName::fromString(data.value(QLatin1String(compilerCommandKeyCppC)).toString());
     m_makeCommand = FileName::fromString(data.value(QLatin1String(makeCommandKeyC)).toString());
     m_targetAbi = Abi(data.value(QLatin1String(targetAbiKeyC)).toString());
     m_predefinedMacros = data.value(QLatin1String(predefinedMacrosKeyC)).toStringList();
@@ -353,7 +377,8 @@ bool CustomToolChain::operator ==(const ToolChain &other) const
         return false;
 
     auto customTc = static_cast<const CustomToolChain *>(&other);
-    return m_compilerCommand == customTc->m_compilerCommand
+    return m_compilerCommandC == customTc->m_compilerCommandC
+            && m_compilerCommandC == customTc->m_compilerCommandC
             && m_makeCommand == customTc->m_makeCommand
             && m_targetAbi == customTc->m_targetAbi
             && m_predefinedMacros == customTc->m_predefinedMacros
@@ -482,7 +507,8 @@ public:
 
 CustomToolChainConfigWidget::CustomToolChainConfigWidget(CustomToolChain *tc) :
     ToolChainConfigWidget(tc),
-    m_compilerCommand(new PathChooser),
+    m_compilerCommandC(new PathChooser),
+    m_compilerCommandCpp(new PathChooser),
     m_makeCommand(new PathChooser),
     m_abiWidget(new AbiWidget),
     m_predefinedMacros(new QPlainTextEdit),
@@ -508,11 +534,14 @@ CustomToolChainConfigWidget::CustomToolChainConfigWidget(CustomToolChain *tc) :
     m_headerPaths->setToolTip(tr("Each line adds a global header lookup path."));
     m_cxx11Flags->setToolTip(tr("Comma-separated list of flags that turn on C++11 support."));
     m_mkspecs->setToolTip(tr("Comma-separated list of mkspecs."));
-    m_compilerCommand->setExpectedKind(PathChooser::ExistingCommand);
-    m_compilerCommand->setHistoryCompleter(QLatin1String("PE.ToolChainCommand.History"));
+    m_compilerCommandC->setExpectedKind(PathChooser::ExistingCommand);
+    m_compilerCommandC->setHistoryCompleter(QLatin1String("PE.ToolChainCommandC.History"));
+    m_compilerCommandCpp->setExpectedKind(PathChooser::ExistingCommand);
+    m_compilerCommandCpp->setHistoryCompleter(QLatin1String("PE.ToolChainCommandCpp.History"));
     m_makeCommand->setExpectedKind(PathChooser::ExistingCommand);
     m_makeCommand->setHistoryCompleter(QLatin1String("PE.MakeCommand.History"));
-    m_mainLayout->addRow(tr("&Compiler path:"), m_compilerCommand);
+    m_mainLayout->addRow(tr("&Compiler path (C):"), m_compilerCommandC);
+    m_mainLayout->addRow(tr("Compiler path (C&++):"), m_compilerCommandCpp);
     m_mainLayout->addRow(tr("&Make path:"), m_makeCommand);
     m_mainLayout->addRow(tr("&ABI:"), m_abiWidget);
     m_mainLayout->addRow(tr("&Predefined macros:"), m_predefinedDetails);
@@ -528,7 +557,8 @@ CustomToolChainConfigWidget::CustomToolChainConfigWidget(CustomToolChain *tc) :
     m_predefinedDetails->updateSummaryText();
     m_headerDetails->updateSummaryText();
 
-    connect(m_compilerCommand, &PathChooser::rawPathChanged, this, &ToolChainConfigWidget::dirty);
+    connect(m_compilerCommandC, &PathChooser::rawPathChanged, this, &ToolChainConfigWidget::dirty);
+    connect(m_compilerCommandCpp, &PathChooser::rawPathChanged, this, &ToolChainConfigWidget::dirty);
     connect(m_makeCommand, &PathChooser::rawPathChanged, this, &ToolChainConfigWidget::dirty);
     connect(m_abiWidget, &AbiWidget::abiChanged, this, &ToolChainConfigWidget::dirty);
     connect(m_predefinedMacros, &QPlainTextEdit::textChanged,
@@ -579,7 +609,8 @@ void CustomToolChainConfigWidget::applyImpl()
     auto tc = static_cast<CustomToolChain *>(toolChain());
     Q_ASSERT(tc);
     QString displayName = tc->displayName();
-    tc->setCompilerCommand(m_compilerCommand->fileName());
+    tc->setCompilerCommand(ToolChain::CLanguage, m_compilerCommandC->fileName());
+    tc->setCompilerCommand(ToolChain::CppLanguage, m_compilerCommandCpp->fileName());
     tc->setMakeCommand(m_makeCommand->fileName());
     tc->setTargetAbi(m_abiWidget->currentAbi());
     tc->setPredefinedMacros(m_predefinedDetails->entries());
@@ -596,7 +627,8 @@ void CustomToolChainConfigWidget::setFromToolchain()
     // subwidgets are not yet connected!
     bool blocked = blockSignals(true);
     auto tc = static_cast<CustomToolChain *>(toolChain());
-    m_compilerCommand->setFileName(tc->compilerCommand());
+    m_compilerCommandC->setFileName(tc->compilerCommand(ToolChain::CLanguage));
+    m_compilerCommandCpp->setFileName(tc->compilerCommand(ToolChain::CppLanguage));
     m_makeCommand->setFileName(FileName::fromString(tc->makeCommand(Environment())));
     m_abiWidget->setAbis(QList<Abi>(), tc->targetAbi());
     m_predefinedMacros->setPlainText(tc->rawPredefinedMacros().join(QLatin1Char('\n')));
@@ -612,7 +644,8 @@ bool CustomToolChainConfigWidget::isDirtyImpl() const
 {
     auto tc = static_cast<CustomToolChain *>(toolChain());
     Q_ASSERT(tc);
-    return m_compilerCommand->fileName() != tc->compilerCommand()
+    return m_compilerCommandC->fileName() != tc->compilerCommand(ToolChain::CLanguage)
+            || m_compilerCommandCpp->fileName() != tc->compilerCommand(ToolChain::CppLanguage)
             || m_makeCommand->path() != tc->makeCommand(Environment())
             || m_abiWidget->currentAbi() != tc->targetAbi()
             || m_predefinedDetails->entries() != tc->rawPredefinedMacros()
diff --git a/src/plugins/projectexplorer/customtoolchain.h b/src/plugins/projectexplorer/customtoolchain.h
index c0d1cd7..93349ee 100644
--- a/src/plugins/projectexplorer/customtoolchain.h
+++ b/src/plugins/projectexplorer/customtoolchain.h
@@ -98,8 +98,8 @@ public:
 
     bool operator ==(const ToolChain &) const override;
 
-    void setCompilerCommand(const Utils::FileName &);
-    Utils::FileName compilerCommand() const override;
+    void setCompilerCommand(Language, const Utils::FileName &);
+    Utils::FileName compilerCommand(Language language) const override;
     void setMakeCommand(const Utils::FileName &);
     QString makeCommand(const Utils::Environment &environment) const override;
 
@@ -123,7 +123,8 @@ protected:
 private:
     explicit CustomToolChain(Detection d);
 
-    Utils::FileName m_compilerCommand;
+    Utils::FileName m_compilerCommandC;
+    Utils::FileName m_compilerCommandCpp;
     Utils::FileName m_makeCommand;
 
     Abi m_targetAbi;
@@ -182,7 +183,8 @@ protected:
 
     void setFromToolchain();
 
-    Utils::PathChooser *m_compilerCommand;
+    Utils::PathChooser *m_compilerCommandC;
+    Utils::PathChooser *m_compilerCommandCpp;
     Utils::PathChooser *m_makeCommand;
     AbiWidget *m_abiWidget;
     QPlainTextEdit *m_predefinedMacros;
diff --git a/src/plugins/projectexplorer/gcctoolchain.cpp b/src/plugins/projectexplorer/gcctoolchain.cpp
index dd05575..e4792c6 100644
--- a/src/plugins/projectexplorer/gcctoolchain.cpp
+++ b/src/plugins/projectexplorer/gcctoolchain.cpp
@@ -58,7 +58,8 @@ using namespace Internal;
 // Helpers:
 // --------------------------------------------------------------------------
 
-static const char compilerCommandKeyC[] = "ProjectExplorer.GccToolChain.Path";
+static const char compilerCommandKeyCC[] = "ProjectExplorer.GccToolChain.PathC";
+static const char compilerCommandKeyCppC[] = "ProjectExplorer.GccToolChain.PathCpp";
 static const char compilerPlatformCodeGenFlagsKeyC[] = "ProjectExplorer.GccToolChain.PlatformCodeGenFlags";
 static const char compilerPlatformLinkerFlagsKeyC[] = "ProjectExplorer.GccToolChain.PlatformLinkerFlags";
 static const char targetAbiKeyC[] = "ProjectExplorer.GccToolChain.TargetAbi";
@@ -224,12 +225,22 @@ GccToolChain::GccToolChain(Core::Id typeId, Detection d) :
     ToolChain(typeId, d)
 { }
 
-void GccToolChain::setCompilerCommand(const FileName &path)
+void GccToolChain::setCompilerCommand(Language language, const FileName &path)
 {
-    if (path == m_compilerCommand)
-        return;
+    switch (language) {
+    case CLanguage:
+        if (path == m_compilerCommandC)
+            return;
+
+        m_compilerCommandC = path;
+        break;
+    case CppLanguage:
+        if (path == m_compilerCommandCpp)
+            return;
 
-    m_compilerCommand = path;
+        m_compilerCommandCpp = path;
+        break;
+    }
 }
 
 void GccToolChain::setSupportedAbis(const QList<Abi> &m_abis)
@@ -282,7 +293,7 @@ QString GccToolChain::defaultDisplayName() const
                                        "%1 (%2 %3 in %4)").arg(typeDisplayName(),
                                                                Abi::toString(m_targetAbi.architecture()),
                                                                Abi::toString(m_targetAbi.wordWidth()),
-                                                               compilerCommand().parentDir().toUserOutput());
+                                                               compilerCommand(CppLanguage).parentDir().toUserOutput());
 }
 
 ToolChain::CompilerFlags GccToolChain::defaultCompilerFlags() const
@@ -330,10 +341,14 @@ QList<Abi> GccToolChain::supportedAbis() const
 
 bool GccToolChain::isValid() const
 {
-    if (m_compilerCommand.isNull())
+    if (m_compilerCommandC.isNull() || m_compilerCommandCpp.isNull())
         return false;
 
-    QFileInfo fi = compilerCommand().toFileInfo();
+    QFileInfo fi = compilerCommand(CLanguage).toFileInfo();
+    if (!fi.isExecutable())
+        return false;
+
+    fi = compilerCommand(CppLanguage).toFileInfo();
     return fi.isExecutable();
 }
 
@@ -397,7 +412,7 @@ QByteArray GccToolChain::predefinedMacros(const QStringList &cxxflags) const
                 || a == QLatin1String("-fPIE") || a == QLatin1String("-fpie"))
             arguments << a;
     }
-    macros = gccPredefinedMacros(m_compilerCommand, reinterpretOptions(arguments),
+    macros = gccPredefinedMacros(m_compilerCommandCpp, reinterpretOptions(arguments),
                                  env.toStringList());
 
     setMacroCache(allCxxflags, macros);
@@ -538,7 +553,7 @@ QList<HeaderPath> GccToolChain::systemHeaderPaths(const QStringList &cxxflags, c
                   << QLatin1String("-v")
                   << QLatin1String("-");
 
-        m_headerPaths = gccHeaderPaths(m_compilerCommand, reinterpretOptions(arguments), env.toStringList());
+        m_headerPaths = gccHeaderPaths(m_compilerCommandCpp, reinterpretOptions(arguments), env.toStringList());
     }
     return m_headerPaths;
 }
@@ -551,7 +566,8 @@ void GccToolChain::addCommandPathToEnvironment(const FileName &command, Environm
 
 void GccToolChain::addToEnvironment(Environment &env) const
 {
-    addCommandPathToEnvironment(m_compilerCommand, env);
+    addCommandPathToEnvironment(m_compilerCommandC, env);
+    addCommandPathToEnvironment(m_compilerCommandCpp, env);
 }
 
 FileNameList GccToolChain::suggestedMkspecList() const
@@ -568,9 +584,9 @@ FileNameList GccToolChain::suggestedMkspecList() const
     if (abi.os() == Abi::MacOS) {
         QString v = version();
         // prefer versioned g++ on mac. This is required to enable building for older Mac OS versions
-        if (v.startsWith(QLatin1String("4.0")) && m_compilerCommand.endsWith(QLatin1String("-4.0")))
+        if (v.startsWith(QLatin1String("4.0")) && m_compilerCommandCpp.endsWith(QLatin1String("-4.0")))
             return FileNameList() << FileName::fromLatin1("macx-g++40");
-        if (v.startsWith(QLatin1String("4.2")) && m_compilerCommand.endsWith(QLatin1String("-4.2")))
+        if (v.startsWith(QLatin1String("4.2")) && m_compilerCommandCpp.endsWith(QLatin1String("-4.2")))
             return FileNameList() << FileName::fromLatin1("macx-g++42");
         return FileNameList() << FileName::fromLatin1("macx-g++");
     }
@@ -605,14 +621,15 @@ IOutputParser *GccToolChain::outputParser() const
     return new GccParser;
 }
 
-void GccToolChain::resetToolChain(const FileName &path)
+void GccToolChain::resetToolChain(const Utils::FileName &compilerCommandC, const Utils::FileName &compilerCommandCpp)
 {
-    if (path == m_compilerCommand)
+    if (compilerCommandC == m_compilerCommandC && compilerCommandCpp == m_compilerCommandCpp)
         return;
 
     bool resetDisplayName = displayName() == defaultDisplayName();
 
-    setCompilerCommand(path);
+    setCompilerCommand(CLanguage, compilerCommandC);
+    setCompilerCommand(CppLanguage, compilerCommandCpp);
 
     Abi currentAbi = m_targetAbi;
     const DetectedAbisResult detectedAbis = detectSupportedAbis();
@@ -633,9 +650,16 @@ void GccToolChain::resetToolChain(const FileName &path)
         toolChainUpdated();
 }
 
-FileName GccToolChain::compilerCommand() const
+FileName GccToolChain::compilerCommand(Language language) const
 {
-    return m_compilerCommand;
+    switch (language) {
+    case CLanguage:
+        return m_compilerCommandC;
+    case CppLanguage:
+        return m_compilerCommandCpp;
+    default:
+        return FileName();
+    }
 }
 
 void GccToolChain::setPlatformCodeGenFlags(const QStringList &flags)
@@ -680,7 +704,8 @@ ToolChain *GccToolChain::clone() const
 QVariantMap GccToolChain::toMap() const
 {
     QVariantMap data = ToolChain::toMap();
-    data.insert(QLatin1String(compilerCommandKeyC), m_compilerCommand.toString());
+    data.insert(QLatin1String(compilerCommandKeyCC), m_compilerCommandC.toString());
+    data.insert(QLatin1String(compilerCommandKeyCppC), m_compilerCommandCpp.toString());
     data.insert(QLatin1String(compilerPlatformCodeGenFlagsKeyC), m_platformCodeGenFlags);
     data.insert(QLatin1String(compilerPlatformLinkerFlagsKeyC), m_platformLinkerFlags);
     data.insert(QLatin1String(targetAbiKeyC), m_targetAbi.toString());
@@ -695,7 +720,8 @@ bool GccToolChain::fromMap(const QVariantMap &data)
     if (!ToolChain::fromMap(data))
         return false;
 
-    m_compilerCommand = FileName::fromString(data.value(QLatin1String(compilerCommandKeyC)).toString());
+    m_compilerCommandC = FileName::fromString(data.value(QLatin1String(compilerCommandKeyCC)).toString());
+    m_compilerCommandCpp = FileName::fromString(data.value(QLatin1String(compilerCommandKeyCppC)).toString());
     m_platformCodeGenFlags = data.value(QLatin1String(compilerPlatformCodeGenFlagsKeyC)).toStringList();
     m_platformLinkerFlags = data.value(QLatin1String(compilerPlatformLinkerFlagsKeyC)).toStringList();
     m_targetAbi = Abi(data.value(QLatin1String(targetAbiKeyC)).toString());
@@ -717,7 +743,9 @@ bool GccToolChain::operator ==(const ToolChain &other) const
         return false;
 
     auto gccTc = static_cast<const GccToolChain *>(&other);
-    return m_compilerCommand == gccTc->m_compilerCommand && m_targetAbi == gccTc->m_targetAbi
+    return m_compilerCommandC == gccTc->m_compilerCommandC
+            && m_compilerCommandCpp == gccTc->m_compilerCommandCpp
+            && m_targetAbi == gccTc->m_targetAbi
             && m_platformCodeGenFlags == gccTc->m_platformCodeGenFlags
             && m_platformLinkerFlags == gccTc->m_platformLinkerFlags;
 }
@@ -741,14 +769,14 @@ GccToolChain::DetectedAbisResult GccToolChain::detectSupportedAbis() const
     Environment env = Environment::systemEnvironment();
     addToEnvironment(env);
     QByteArray macros = predefinedMacros(QStringList());
-    return guessGccAbi(m_compilerCommand, env.toStringList(), macros, platformCodeGenFlags());
+    return guessGccAbi(m_compilerCommandCpp, env.toStringList(), macros, platformCodeGenFlags());
 }
 
 QString GccToolChain::detectVersion() const
 {
     Environment env = Environment::systemEnvironment();
     addToEnvironment(env);
-    return gccVersion(m_compilerCommand, env.toStringList());
+    return gccVersion(m_compilerCommandCpp, env.toStringList());
 }
 
 // --------------------------------------------------------------------------
@@ -775,12 +803,12 @@ QList<ToolChain *> GccToolChainFactory::autoDetect(const QList<ToolChain *> &alr
     QList<ToolChain *> tcs;
     if (HostOsInfo::isMacHost()) {
         // Old mac compilers needed to support macx-gccXY mkspecs:
-        tcs.append(autoDetectToolchains(QLatin1String("g++-4.0"), Abi::hostAbi(),
+        tcs.append(autoDetectToolchains(QLatin1String("gcc-4.0"), QLatin1String("g++-4.0"), Abi::hostAbi(),
                                         Constants::GCC_TOOLCHAIN_TYPEID, alreadyKnown));
-        tcs.append(autoDetectToolchains(QLatin1String("g++-4.2"), Abi::hostAbi(),
+        tcs.append(autoDetectToolchains(QLatin1String("gcc-4.2"), QLatin1String("g++-4.2"), Abi::hostAbi(),
                                         Constants::GCC_TOOLCHAIN_TYPEID, alreadyKnown));
     }
-    tcs.append(autoDetectToolchains(QLatin1String("g++"), Abi::hostAbi(),
+    tcs.append(autoDetectToolchains(QLatin1String("gcc"), QLatin1String("g++"), Abi::hostAbi(),
                                     Constants::GCC_TOOLCHAIN_TYPEID,alreadyKnown));
 
     return tcs;
@@ -807,7 +835,8 @@ GccToolChain *GccToolChainFactory::createToolChain(bool autoDetect)
     return new GccToolChain(autoDetect ? ToolChain::AutoDetection : ToolChain::ManualDetection);
 }
 
-QList<ToolChain *> GccToolChainFactory::autoDetectToolchains(const QString &compiler,
+QList<ToolChain *> GccToolChainFactory::autoDetectToolchains(const QString &cCompiler,
+                                                             const QString &cppCompiler,
                                                              const Abi &requiredAbi,
                                                              const Core::Id requiredTypeId,
                                                              const QList<ToolChain *> &alreadyKnown)
@@ -815,21 +844,24 @@ QList<ToolChain *> GccToolChainFactory::autoDetectToolchains(const QString &comp
     QList<ToolChain *> result;
 
     Environment systemEnvironment = Environment::systemEnvironment();
-    const FileName compilerPath = systemEnvironment.searchInPath(compiler);
-    if (compilerPath.isEmpty())
+    const FileName cCompilerPath = systemEnvironment.searchInPath(cCompiler);
+    const FileName cppCompilerPath = systemEnvironment.searchInPath(cppCompiler);
+    if (cCompilerPath.isEmpty() || cppCompilerPath.isEmpty())
         return result;
 
-    result = Utils::filtered(alreadyKnown, [requiredTypeId, compilerPath](ToolChain *tc) {
+    result = Utils::filtered(alreadyKnown, [requiredTypeId, cCompilerPath, cppCompilerPath](ToolChain *tc) {
                                                return tc->typeId() == requiredTypeId
-                                                   && tc->compilerCommand() == compilerPath;
+                                                   && tc->compilerCommand(ToolChain::CLanguage) == cCompilerPath
+                                                   && tc->compilerCommand(ToolChain::CppLanguage) == cppCompilerPath;
                                            });
     if (!result.isEmpty())
         return result;
 
-    GccToolChain::addCommandPathToEnvironment(compilerPath, systemEnvironment);
+    GccToolChain::addCommandPathToEnvironment(cCompilerPath, systemEnvironment);
+    GccToolChain::addCommandPathToEnvironment(cppCompilerPath, systemEnvironment);
     QByteArray macros
-            = gccPredefinedMacros(compilerPath, gccPredefinedMacrosOptions(), systemEnvironment.toStringList());
-    const GccToolChain::DetectedAbisResult detectedAbis = guessGccAbi(compilerPath,
+            = gccPredefinedMacros(cppCompilerPath, gccPredefinedMacrosOptions(), systemEnvironment.toStringList());
+    const GccToolChain::DetectedAbisResult detectedAbis = guessGccAbi(cppCompilerPath,
                                                                       systemEnvironment.toStringList(),
                                                                       macros);
     QList<Abi> abiList = detectedAbis.supportedAbis;
@@ -846,7 +878,8 @@ QList<ToolChain *> GccToolChainFactory::autoDetectToolchains(const QString &comp
             return result;
 
         tc->setMacroCache(QStringList(), macros);
-        tc->setCompilerCommand(compilerPath);
+        tc->setCompilerCommand(ToolChain::CLanguage, cCompilerPath);
+        tc->setCompilerCommand(ToolChain::CppLanguage, cppCompilerPath);
         tc->setSupportedAbis(abiList);
         tc->setTargetAbi(abi);
         tc->setOriginalTargetTriple(detectedAbis.originalTargetTriple);
@@ -864,16 +897,21 @@ QList<ToolChain *> GccToolChainFactory::autoDetectToolchains(const QString &comp
 
 GccToolChainConfigWidget::GccToolChainConfigWidget(GccToolChain *tc) :
     ToolChainConfigWidget(tc),
-    m_compilerCommand(new PathChooser),
+    m_compilerCommandC(new PathChooser),
+    m_compilerCommandCpp(new PathChooser),
     m_abiWidget(new AbiWidget)
 {
     Q_ASSERT(tc);
 
     const QStringList gnuVersionArgs = QStringList(QLatin1String("--version"));
-    m_compilerCommand->setExpectedKind(PathChooser::ExistingCommand);
-    m_compilerCommand->setCommandVersionArguments(gnuVersionArgs);
-    m_compilerCommand->setHistoryCompleter(QLatin1String("PE.Gcc.Command.History"));
-    m_mainLayout->addRow(tr("&Compiler path:"), m_compilerCommand);
+    m_compilerCommandC->setExpectedKind(PathChooser::ExistingCommand);
+    m_compilerCommandC->setCommandVersionArguments(gnuVersionArgs);
+    m_compilerCommandC->setHistoryCompleter(QLatin1String("PE.Gcc.Command.History"));
+    m_mainLayout->addRow(tr("&Compiler path (C):"), m_compilerCommandC);
+    m_compilerCommandCpp->setExpectedKind(PathChooser::ExistingCommand);
+    m_compilerCommandCpp->setCommandVersionArguments(gnuVersionArgs);
+    m_compilerCommandCpp->setHistoryCompleter(QLatin1String("PE.G++.Command.History"));
+    m_mainLayout->addRow(tr("Compiler path (C&++):"), m_compilerCommandCpp);
     m_platformCodeGenFlagsLineEdit = new QLineEdit(this);
     m_platformCodeGenFlagsLineEdit->setText(QtcProcess::joinArgs(tc->platformCodeGenFlags()));
     m_mainLayout->addRow(tr("Platform codegen flags:"), m_platformCodeGenFlagsLineEdit);
@@ -887,7 +925,10 @@ GccToolChainConfigWidget::GccToolChainConfigWidget(GccToolChain *tc) :
 
     setFromToolchain();
 
-    connect(m_compilerCommand, &PathChooser::rawPathChanged,
+    // Use the C++ compiler to detect ABI and macros.
+    connect(m_compilerCommandC, &PathChooser::rawPathChanged,
+            this, &GccToolChainConfigWidget::dirty);
+    connect(m_compilerCommandCpp, &PathChooser::rawPathChanged,
             this, &GccToolChainConfigWidget::handleCompilerCommandChange);
     connect(m_platformCodeGenFlagsLineEdit, &QLineEdit::editingFinished,
             this, &GccToolChainConfigWidget::handlePlatformCodeGenFlagsChange);
@@ -904,7 +945,8 @@ void GccToolChainConfigWidget::applyImpl()
     auto tc = static_cast<GccToolChain *>(toolChain());
     Q_ASSERT(tc);
     QString displayName = tc->displayName();
-    tc->setCompilerCommand(m_compilerCommand->fileName());
+    tc->setCompilerCommand(ToolChain::CLanguage, m_compilerCommandC->fileName());
+    tc->setCompilerCommand(ToolChain::CppLanguage, m_compilerCommandCpp->fileName());
     tc->setSupportedAbis(m_abiWidget->supportedAbis());
     tc->setTargetAbi(m_abiWidget->currentAbi());
     tc->setOriginalTargetTriple(tc->detectSupportedAbis().originalTargetTriple);
@@ -919,11 +961,12 @@ void GccToolChainConfigWidget::setFromToolchain()
     // subwidgets are not yet connected!
     bool blocked = blockSignals(true);
     auto tc = static_cast<GccToolChain *>(toolChain());
-    m_compilerCommand->setFileName(tc->compilerCommand());
+    m_compilerCommandC->setFileName(tc->compilerCommand(ToolChain::CLanguage));
+    m_compilerCommandCpp->setFileName(tc->compilerCommand(ToolChain::CppLanguage));
     m_platformCodeGenFlagsLineEdit->setText(QtcProcess::joinArgs(tc->platformCodeGenFlags()));
     m_platformLinkerFlagsLineEdit->setText(QtcProcess::joinArgs(tc->platformLinkerFlags()));
     m_abiWidget->setAbis(tc->supportedAbis(), tc->targetAbi());
-    if (!m_isReadOnly && !m_compilerCommand->path().isEmpty())
+    if (!m_isReadOnly && !m_compilerCommandC->path().isEmpty() && !m_compilerCommandCpp->path().isEmpty())
         m_abiWidget->setEnabled(true);
     blockSignals(blocked);
 }
@@ -932,7 +975,8 @@ bool GccToolChainConfigWidget::isDirtyImpl() const
 {
     auto tc = static_cast<GccToolChain *>(toolChain());
     Q_ASSERT(tc);
-    return m_compilerCommand->fileName() != tc->compilerCommand()
+    return m_compilerCommandC->fileName() != tc->compilerCommand(ToolChain::CLanguage)
+            || m_compilerCommandCpp->fileName() != tc->compilerCommand(ToolChain::CppLanguage)
             || m_platformCodeGenFlagsLineEdit->text() != QtcProcess::joinArgs(tc->platformCodeGenFlags())
             || m_platformLinkerFlagsLineEdit->text() != QtcProcess::joinArgs(tc->platformLinkerFlags())
             || m_abiWidget->currentAbi() != tc->targetAbi();
@@ -940,7 +984,8 @@ bool GccToolChainConfigWidget::isDirtyImpl() const
 
 void GccToolChainConfigWidget::makeReadOnlyImpl()
 {
-    m_compilerCommand->setReadOnly(true);
+    m_compilerCommandC->setReadOnly(true);
+    m_compilerCommandCpp->setReadOnly(true);
     m_abiWidget->setEnabled(false);
     m_platformCodeGenFlagsLineEdit->setEnabled(false);
     m_platformLinkerFlagsLineEdit->setEnabled(false);
@@ -968,7 +1013,7 @@ void GccToolChainConfigWidget::handleCompilerCommandChange()
     bool haveCompiler = false;
     Abi currentAbi = m_abiWidget->currentAbi();
     bool customAbi = m_abiWidget->isCustomAbi();
-    FileName path = m_compilerCommand->fileName();
+    FileName path = m_compilerCommandCpp->fileName();
     QList<Abi> abiList;
 
     if (!path.isEmpty()) {
@@ -1124,7 +1169,7 @@ ClangToolChainFactory::ClangToolChainFactory()
 
 QList<ToolChain *> ClangToolChainFactory::autoDetect(const QList<ToolChain *> &alreadyKnown)
 {
-    return autoDetectToolchains(QLatin1String("clang++"), Abi::hostAbi(),
+    return autoDetectToolchains(QLatin1String("clang"), QLatin1String("clang++"), Abi::hostAbi(),
                                 Constants::CLANG_TOOLCHAIN_TYPEID, alreadyKnown);
 }
 
@@ -1205,7 +1250,7 @@ QList<ToolChain *> MingwToolChainFactory::autoDetect(const QList<ToolChain *> &a
 {
     Abi ha = Abi::hostAbi();
     ha = Abi(ha.architecture(), Abi::WindowsOS, Abi::WindowsMSysFlavor, Abi::PEFormat, ha.wordWidth());
-    return autoDetectToolchains(QLatin1String("g++"), ha,
+    return autoDetectToolchains(QLatin1String("gcc"), QLatin1String("g++"), ha,
                                 Constants::MINGW_TOOLCHAIN_TYPEID, alreadyKnown);
 }
 
@@ -1281,7 +1326,7 @@ LinuxIccToolChainFactory::LinuxIccToolChainFactory()
 
 QList<ToolChain *> LinuxIccToolChainFactory::autoDetect(const QList<ToolChain *> &alreadyKnown)
 {
-    return autoDetectToolchains(QLatin1String("icpc"), Abi::hostAbi(),
+    return autoDetectToolchains(QLatin1String("icpc"), QLatin1String("icpc"), Abi::hostAbi(),
                                 Constants::LINUXICC_TOOLCHAIN_TYPEID, alreadyKnown);
 }
 
diff --git a/src/plugins/projectexplorer/gcctoolchain.h b/src/plugins/projectexplorer/gcctoolchain.h
index cd651ab..47b9a06 100644
--- a/src/plugins/projectexplorer/gcctoolchain.h
+++ b/src/plugins/projectexplorer/gcctoolchain.h
@@ -79,8 +79,8 @@ public:
 
     bool operator ==(const ToolChain &) const override;
 
-    void resetToolChain(const Utils::FileName &);
-    Utils::FileName compilerCommand() const override;
+    void resetToolChain(const Utils::FileName &compilerCommandC, const Utils::FileName &compilerCommandCpp);
+    Utils::FileName compilerCommand(Language language) const override;
     void setPlatformCodeGenFlags(const QStringList &);
     QStringList platformCodeGenFlags() const;
     void setPlatformLinkerFlags(const QStringList &);
@@ -110,7 +110,7 @@ protected:
 
     typedef QPair<QStringList, QByteArray> CacheItem;
 
-    void setCompilerCommand(const Utils::FileName &path);
+    void setCompilerCommand(Language language, const Utils::FileName &path);
     void setSupportedAbis(const QList<Abi> &m_abis);
     void setOriginalTargetTriple(const QString &targetTriple);
     void setMacroCache(const QStringList &allCxxflags, const QByteArray &macroCache) const;
@@ -149,7 +149,8 @@ private:
 
     void updateSupportedAbis() const;
 
-    Utils::FileName m_compilerCommand;
+    Utils::FileName m_compilerCommandC;
+    Utils::FileName m_compilerCommandCpp;
     QStringList m_platformCodeGenFlags;
     QStringList m_platformLinkerFlags;
 
diff --git a/src/plugins/projectexplorer/gcctoolchainfactories.h b/src/plugins/projectexplorer/gcctoolchainfactories.h
index cdebccc..1c3bd45 100644
--- a/src/plugins/projectexplorer/gcctoolchainfactories.h
+++ b/src/plugins/projectexplorer/gcctoolchainfactories.h
@@ -60,7 +60,9 @@ public:
 
 protected:
     virtual GccToolChain *createToolChain(bool autoDetect);
-    QList<ToolChain *> autoDetectToolchains(const QString &compiler, const Abi &requiredAbi,
+    QList<ToolChain *> autoDetectToolchains(const QString &cCompiler,
+                                            const QString &cppCompiler,
+                                            const Abi &requiredAbi,
                                             const Core::Id requiredTypeId,
                                             const QList<ToolChain *> &alreadyKnown);
 };
@@ -89,7 +91,8 @@ private:
 
     void setFromToolchain();
 
-    Utils::PathChooser *m_compilerCommand;
+    Utils::PathChooser *m_compilerCommandC;
+    Utils::PathChooser *m_compilerCommandCpp;
     QLineEdit *m_platformCodeGenFlagsLineEdit;
     QLineEdit *m_platformLinkerFlagsLineEdit;
     AbiWidget *m_abiWidget;
diff --git a/src/plugins/projectexplorer/kitinformation.cpp b/src/plugins/projectexplorer/kitinformation.cpp
index 7ecb304..3e87f6a 100644
--- a/src/plugins/projectexplorer/kitinformation.cpp
+++ b/src/plugins/projectexplorer/kitinformation.cpp
@@ -235,7 +235,19 @@ void ToolChainKitInformation::addToMacroExpander(Kit *kit, Utils::MacroExpander
     expander->registerVariable("Compiler:Executable", tr("Path to the compiler executable"),
                                [this, kit]() -> QString {
                                    const ToolChain *tc = toolChain(kit);
-                                   return tc ? tc->compilerCommand().toString() : QString();
+                                   return tc ? tc->compilerCommand(ToolChain::CppLanguage).toString() : QString();
+                               });
+
+    expander->registerVariable("Compiler:Executable:C", tr("Path to the C compiler executable"),
+                               [this, kit]() -> QString {
+                                   const ToolChain *tc = toolChain(kit);
+                                   return tc ? tc->compilerCommand(ToolChain::CLanguage).toString() : QString();
+                               });
+
+    expander->registerVariable("Compiler:Executable:C++", tr("Path to the C++ compiler executable"),
+                               [this, kit]() -> QString {
+                                   const ToolChain *tc = toolChain(kit);
+                                   return tc ? tc->compilerCommand(ToolChain::CppLanguage).toString() : QString();
                                });
 }
 
diff --git a/src/plugins/projectexplorer/msvctoolchain.h b/src/plugins/projectexplorer/msvctoolchain.h
index d544ceb..247f13e 100644
--- a/src/plugins/projectexplorer/msvctoolchain.h
+++ b/src/plugins/projectexplorer/msvctoolchain.h
@@ -100,7 +100,7 @@ public:
     QString typeDisplayName() const override;
     QList<Utils::FileName> suggestedMkspecList() const override;
     void addToEnvironment(Utils::Environment &env) const override;
-    Utils::FileName compilerCommand() const override { return m_compiler; }
+    Utils::FileName compilerCommand(Language) const override { return m_compiler; }
     IOutputParser *outputParser() const override;
     ToolChain *clone() const override;
     QVariantMap toMap() const override;
diff --git a/src/plugins/projectexplorer/settingsaccessor.cpp b/src/plugins/projectexplorer/settingsaccessor.cpp
index 2851496..8381441 100644
--- a/src/plugins/projectexplorer/settingsaccessor.cpp
+++ b/src/plugins/projectexplorer/settingsaccessor.cpp
@@ -2153,7 +2153,7 @@ QVariantMap UserFileVersion11Upgrader::upgrade(const QVariantMap &map)
                     debuggerPath = debuggerPath + QLatin1Char('.') + split.at(j);
 
                 foreach (ToolChain *tc, ToolChainManager::toolChains()) {
-                    if ((tc->compilerCommand() == FileName::fromString(compilerPath))
+                    if ((tc->compilerCommand(ToolChain::CppLanguage) == FileName::fromString(compilerPath))
                             && (tc->targetAbi() == compilerAbi)) {
                         tcId = QString::fromUtf8(tc->id());
                         break;
diff --git a/src/plugins/projectexplorer/toolchain.h b/src/plugins/projectexplorer/toolchain.h
index cac15dc..ee1b4ea 100644
--- a/src/plugins/projectexplorer/toolchain.h
+++ b/src/plugins/projectexplorer/toolchain.h
@@ -110,7 +110,12 @@ public:
     virtual void addToEnvironment(Utils::Environment &env) const = 0;
     virtual QString makeCommand(const Utils::Environment &env) const = 0;
 
-    virtual Utils::FileName compilerCommand() const = 0;
+    enum Language {
+        CLanguage,
+        CppLanguage
+    };
+
+    virtual Utils::FileName compilerCommand(Language language) const = 0;
     virtual IOutputParser *outputParser() const = 0;
 
     virtual bool operator ==(const ToolChain &) const;
diff --git a/src/plugins/projectexplorer/toolchainmanager.cpp b/src/plugins/projectexplorer/toolchainmanager.cpp
index 866f74b..29b028c 100644
--- a/src/plugins/projectexplorer/toolchainmanager.cpp
+++ b/src/plugins/projectexplorer/toolchainmanager.cpp
@@ -448,7 +448,7 @@ public:
     { Q_UNUSED(cxxflags); Q_UNUSED(sysRoot); return QList<HeaderPath>(); }
     void addToEnvironment(Environment &env) const override { Q_UNUSED(env); }
     QString makeCommand(const Environment &env) const override { Q_UNUSED(env); return QLatin1String("make"); }
-    FileName compilerCommand() const override { return Utils::FileName::fromString(QLatin1String("/tmp/test/gcc")); }
+    FileName compilerCommand(Language) const override { return Utils::FileName::fromString(QLatin1String("/tmp/test/gcc")); }
     IOutputParser *outputParser() const override { return nullptr; }
     ToolChainConfigWidget *configurationWidget() override { return nullptr; }
     TTC *clone() const override { return new TTC(*this); }
diff --git a/src/plugins/qbsprojectmanager/defaultpropertyprovider.cpp b/src/plugins/qbsprojectmanager/defaultpropertyprovider.cpp
index 8827308..76cd51d 100644
--- a/src/plugins/qbsprojectmanager/defaultpropertyprovider.cpp
+++ b/src/plugins/qbsprojectmanager/defaultpropertyprovider.cpp
@@ -236,7 +236,7 @@ QVariantMap DefaultPropertyProvider::autoGeneratedProperties(const ProjectExplor
         }
     }
 
-    Utils::FileName cxx = tc->compilerCommand();
+    Utils::FileName cxx = tc->compilerCommand(ProjectExplorer::ToolChain::CppLanguage);
     const QFileInfo cxxFileInfo = cxx.toFileInfo();
     QString compilerName = cxxFileInfo.fileName();
     const QString toolchainPrefix = extractToolchainPrefix(&compilerName);
diff --git a/src/plugins/qnx/qnxconfiguration.cpp b/src/plugins/qnx/qnxconfiguration.cpp
index 6121d07..27cbc5c 100644
--- a/src/plugins/qnx/qnxconfiguration.cpp
+++ b/src/plugins/qnx/qnxconfiguration.cpp
@@ -204,7 +204,7 @@ void QnxConfiguration::deactivate()
     QList<DebuggerItem> debuggersToRemove;
     foreach (ToolChain *tc,
              ToolChainManager::toolChains()) {
-        if (tc->compilerCommand() == qccCompilerPath())
+        if (tc->compilerCommand(ToolChain::CppLanguage) == qccCompilerPath())
             toolChainsToRemove.append(tc);
     }
 
@@ -234,7 +234,7 @@ bool QnxConfiguration::isActive() const
     bool hasToolChain = false;
     bool hasDebugger = false;
     foreach (ToolChain *tc, ToolChainManager::toolChains()) {
-        if (tc->compilerCommand() == qccCompilerPath()) {
+        if (tc->compilerCommand(ToolChain::CppLanguage) == qccCompilerPath()) {
             hasToolChain = true;
             break;
         }
@@ -294,7 +294,7 @@ QnxToolChain *QnxConfiguration::createToolChain(QnxArchitecture arch, const QStr
                                                 const QString &ndkPath)
 {
     QnxToolChain *toolChain = new QnxToolChain(ToolChain::AutoDetection);
-    toolChain->resetToolChain(m_qccCompiler);
+    toolChain->resetToolChain(m_qccCompiler, m_qccCompiler);
     toolChain->setTargetAbi(Abi((arch == Qnx::ArmLeV7) ? Abi::ArmArchitecture : Abi::X86Architecture,
                                 Abi::LinuxOS, Abi::GenericLinuxFlavor, Abi::ElfFormat, 32));
     toolChain->setDisplayName(displayName);
diff --git a/src/plugins/qnx/qnxtoolchain.cpp b/src/plugins/qnx/qnxtoolchain.cpp
index ad0cd53..11c478c 100644
--- a/src/plugins/qnx/qnxtoolchain.cpp
+++ b/src/plugins/qnx/qnxtoolchain.cpp
@@ -187,7 +187,7 @@ QnxToolChainConfigWidget::QnxToolChainConfigWidget(QnxToolChain *tc)
 {
     m_compilerCommand->setExpectedKind(PathChooser::ExistingCommand);
     m_compilerCommand->setHistoryCompleter(QLatin1String("Qnx.ToolChain.History"));
-    m_compilerCommand->setFileName(tc->compilerCommand());
+    m_compilerCommand->setFileName(tc->compilerCommand(ToolChain::CppLanguage));
     m_compilerCommand->setEnabled(!tc->isAutoDetected());
 
     m_ndkPath->setExpectedKind(PathChooser::ExistingDirectory);
@@ -216,7 +216,7 @@ void QnxToolChainConfigWidget::applyImpl()
     QnxToolChain *tc = static_cast<QnxToolChain *>(toolChain());
     Q_ASSERT(tc);
     QString displayName = tc->displayName();
-    tc->resetToolChain(m_compilerCommand->fileName());
+    tc->resetToolChain(m_compilerCommand->fileName(), m_compilerCommand->fileName());
     tc->setDisplayName(displayName); // reset display name
     tc->setNdkPath(m_ndkPath->fileName().toString());
     tc->setTargetAbi(m_abiWidget->currentAbi());
@@ -227,7 +227,7 @@ void QnxToolChainConfigWidget::discardImpl()
     // subwidgets are not yet connected!
     bool blocked = blockSignals(true);
     QnxToolChain *tc = static_cast<QnxToolChain *>(toolChain());
-    m_compilerCommand->setFileName(tc->compilerCommand());
+    m_compilerCommand->setFileName(tc->compilerCommand(ToolChain::CppLanguage));
     m_ndkPath->setPath(tc->ndkPath());
     m_abiWidget->setAbis(tc->supportedAbis(), tc->targetAbi());
     if (!m_compilerCommand->path().isEmpty())
@@ -239,7 +239,7 @@ bool QnxToolChainConfigWidget::isDirtyImpl() const
 {
     QnxToolChain *tc = static_cast<QnxToolChain *>(toolChain());
     Q_ASSERT(tc);
-    return m_compilerCommand->fileName() != tc->compilerCommand()
+    return m_compilerCommand->fileName() != tc->compilerCommand(ToolChain::CppLanguage)
             || m_ndkPath->path() != tc->ndkPath()
             || m_abiWidget->currentAbi() != tc->targetAbi();
 }
diff --git a/src/tools/sdktool/addkitoperation.cpp b/src/tools/sdktool/addkitoperation.cpp
index 999db68..30be353 100644
--- a/src/tools/sdktool/addkitoperation.cpp
+++ b/src/tools/sdktool/addkitoperation.cpp
@@ -268,6 +268,7 @@ bool AddKitOperation::test() const
     QVariantMap tcMap = AddToolChainOperation::initializeToolChains();
     tcMap = AddToolChainOperation::addToolChain(tcMap, QLatin1String("{tc-id}"), QLatin1String("TC"),
                                                 QLatin1String("/usr/bin/gcc"),
+                                                QLatin1String("/usr/bin/g++"),
                                                 QLatin1String("x86-linux-generic-elf-32bit"),
                                                 QLatin1String("x86-linux-generic-elf-32bit"),
                                                 KeyValuePairList());
diff --git a/src/tools/sdktool/addtoolchainoperation.cpp b/src/tools/sdktool/addtoolchainoperation.cpp
index 6bb0db9..e79b212 100644
--- a/src/tools/sdktool/addtoolchainoperation.cpp
+++ b/src/tools/sdktool/addtoolchainoperation.cpp
@@ -48,7 +48,8 @@ const char DISPLAYNAME[] = "ProjectExplorer.ToolChain.DisplayName";
 const char AUTODETECTED[] = "ProjectExplorer.ToolChain.Autodetect";
 
 // GCC ToolChain:
-const char PATH[] = "ProjectExplorer.GccToolChain.Path";
+const char CPATH[] = "ProjectExplorer.GccToolChain.PathC";
+const char CPPPATH[] = "ProjectExplorer.GccToolChain.PathCpp";
 const char TARGET_ABI[] = "ProjectExplorer.GccToolChain.TargetAbi";
 const char SUPPORTED_ABIS[] = "ProjectExplorer.GccToolChain.SupportedAbis";
 
@@ -66,7 +67,8 @@ QString AddToolChainOperation::argumentsHelpText() const
 {
     return QLatin1String("    --id <ID>                                  id of the new tool chain (required).\n"
                          "    --name <NAME>                              display name of the new tool chain (required).\n"
-                         "    --path <PATH>                              path to the compiler (required).\n"
+                         "    --cpath <PATH>                             path to the C compiler (required).\n"
+                         "    --c++path <PATH>                           path to the C++ compiler (required).\n"
                          "    --abi <ABI STRING>                         ABI of the compiler (required).\n"
                          "    --supportedAbis <ABI STRING>,<ABI STRING>  list of ABIs supported by the compiler.\n"
                          "    <KEY> <TYPE:VALUE>                         extra key value pairs\n");
@@ -95,9 +97,15 @@ bool AddToolChainOperation::setArguments(const QStringList &args)
             continue;
         }
 
-        if (current == QLatin1String("--path")) {
+        if (current == QLatin1String("--cpath")) {
             ++i; // skip next;
-            m_path = QDir::fromNativeSeparators(next);
+            m_cPath = QDir::fromNativeSeparators(next);
+            continue;
+        }
+
+        if (current == QLatin1String("--c++path")) {
+            ++i; // skip next;
+            m_cppPath = QDir::fromNativeSeparators(next);
             continue;
         }
 
@@ -133,12 +141,14 @@ bool AddToolChainOperation::setArguments(const QStringList &args)
         std::cerr << "No id given for tool chain." << std::endl;
     if (m_displayName.isEmpty())
         std::cerr << "No name given for tool chain." << std::endl;
-    if (m_path.isEmpty())
-        std::cerr << "No path given for tool chain." << std::endl;
+    if (m_cPath.isEmpty())
+        std::cerr << "No path given for C tool chain." << std::endl;
+    if (m_cppPath.isEmpty())
+        std::cerr << "No path given for C++ tool chain." << std::endl;
     if (m_targetAbi.isEmpty())
         std::cerr << "No target abi given for tool chain." << std::endl;
 
-    return !m_id.isEmpty() && !m_displayName.isEmpty() && !m_path.isEmpty() && !m_targetAbi.isEmpty();
+    return !m_id.isEmpty() && !m_displayName.isEmpty() && !m_cPath.isEmpty() && !m_cppPath.isEmpty() && !m_targetAbi.isEmpty();
 }
 
 int AddToolChainOperation::execute() const
@@ -147,7 +157,7 @@ int AddToolChainOperation::execute() const
     if (map.isEmpty())
         map = initializeToolChains();
 
-    QVariantMap result = addToolChain(map, m_id, m_displayName, m_path, m_targetAbi, m_supportedAbis, m_extra);
+    QVariantMap result = addToolChain(map, m_id, m_displayName, m_cPath, m_cppPath, m_targetAbi, m_supportedAbis, m_extra);
     if (result.isEmpty() || map == result)
         return 2;
 
@@ -160,8 +170,8 @@ bool AddToolChainOperation::test() const
     QVariantMap map = initializeToolChains();
 
     // Add toolchain:
-    map = addToolChain(map, QLatin1String("testId"), QLatin1String("name"), QLatin1String("/tmp/test"),
-                            QLatin1String("test-abi"), QLatin1String("test-abi,test-abi2"),
+    map = addToolChain(map, QLatin1String("testId"), QLatin1String("name"), QLatin1String("/tmp/test/c"),
+                            QLatin1String("/tmp/test/c++"), QLatin1String("test-abi"), QLatin1String("test-abi,test-abi2"),
                             KeyValuePairList() << KeyValuePair(QLatin1String("ExtraKey"), QVariant(QLatin1String("ExtraValue"))));
     if (map.value(QLatin1String(COUNT)).toInt() != 1
             || !map.contains(QString::fromLatin1(PREFIX) + QLatin1Char('0')))
@@ -171,22 +181,23 @@ bool AddToolChainOperation::test() const
             || tcData.value(QLatin1String(ID)).toString() != QLatin1String("testId")
             || tcData.value(QLatin1String(DISPLAYNAME)).toString() != QLatin1String("name")
             || tcData.value(QLatin1String(AUTODETECTED)).toBool() != true
-            || tcData.value(QLatin1String(PATH)).toString() != QLatin1String("/tmp/test")
+            || tcData.value(QLatin1String(CPATH)).toString() != QLatin1String("/tmp/test/c")
+            || tcData.value(QLatin1String(CPPPATH)).toString() != QLatin1String("/tmp/test/cpp")
             || tcData.value(QLatin1String(TARGET_ABI)).toString() != QLatin1String("test-abi")
             || tcData.value(QLatin1String(SUPPORTED_ABIS)).toList().count() != 2
             || tcData.value(QLatin1String("ExtraKey")).toString() != QLatin1String("ExtraValue"))
         return false;
 
     // Ignore same Id:
-    QVariantMap unchanged = addToolChain(map, QLatin1String("testId"), QLatin1String("name2"), QLatin1String("/tmp/test2"),
-                                              QLatin1String("test-abi2"), QLatin1String("test-abi2,test-abi3"),
+    QVariantMap unchanged = addToolChain(map, QLatin1String("testId"), QLatin1String("name2"), QLatin1String("/tmp/test2/c"),
+                                              QLatin1String("/tmp/test2/c++"), QLatin1String("test-abi2"), QLatin1String("test-abi2,test-abi3"),
                                               KeyValuePairList() << KeyValuePair(QLatin1String("ExtraKey"), QVariant(QLatin1String("ExtraValue2"))));
     if (!unchanged.isEmpty())
         return false;
 
     // Make sure name stays unique:
-    map = addToolChain(map, QLatin1String("{some-tc-id}"), QLatin1String("name"), QLatin1String("/tmp/test"),
-                            QLatin1String("test-abi"), QLatin1String("test-abi,test-abi2"),
+    map = addToolChain(map, QLatin1String("{some-tc-id}"), QLatin1String("name"), QLatin1String("/tmp/test/c"),
+                            QLatin1String("/tmp/test/c++"), QLatin1String("test-abi"), QLatin1String("test-abi,test-abi2"),
                             KeyValuePairList() << KeyValuePair(QLatin1String("ExtraKey"), QVariant(QLatin1String("ExtraValue"))));
     if (map.value(QLatin1String(COUNT)).toInt() != 2
             || !map.contains(QString::fromLatin1(PREFIX) + QLatin1Char('0'))
@@ -197,7 +208,8 @@ bool AddToolChainOperation::test() const
             || tcData.value(QLatin1String(ID)).toString() != QLatin1String("testId")
             || tcData.value(QLatin1String(DISPLAYNAME)).toString() != QLatin1String("name")
             || tcData.value(QLatin1String(AUTODETECTED)).toBool() != true
-            || tcData.value(QLatin1String(PATH)).toString() != QLatin1String("/tmp/test")
+            || tcData.value(QLatin1String(CPATH)).toString() != QLatin1String("/tmp/test/c")
+            || tcData.value(QLatin1String(CPPPATH)).toString() != QLatin1String("/tmp/test/c++")
             || tcData.value(QLatin1String(TARGET_ABI)).toString() != QLatin1String("test-abi")
             || tcData.value(QLatin1String(SUPPORTED_ABIS)).toList().count() != 2
             || tcData.value(QLatin1String("ExtraKey")).toString() != QLatin1String("ExtraValue"))
@@ -207,7 +219,8 @@ bool AddToolChainOperation::test() const
                 || tcData.value(QLatin1String(ID)).toString() != QLatin1String("{some-tc-id}")
                 || tcData.value(QLatin1String(DISPLAYNAME)).toString() != QLatin1String("name2")
                 || tcData.value(QLatin1String(AUTODETECTED)).toBool() != true
-                || tcData.value(QLatin1String(PATH)).toString() != QLatin1String("/tmp/test")
+                || tcData.value(QLatin1String(CPATH)).toString() != QLatin1String("/tmp/test/c")
+                || tcData.value(QLatin1String(CPPPATH)).toString() != QLatin1String("/tmp/test/c++")
                 || tcData.value(QLatin1String(TARGET_ABI)).toString() != QLatin1String("test-abi")
                 || tcData.value(QLatin1String(SUPPORTED_ABIS)).toList().count() != 2
                 || tcData.value(QLatin1String("ExtraKey")).toString() != QLatin1String("ExtraValue"))
@@ -219,8 +232,9 @@ bool AddToolChainOperation::test() const
 
 QVariantMap AddToolChainOperation::addToolChain(const QVariantMap &map,
                                                 const QString &id, const QString &displayName,
-                                                const QString &path, const QString &abi,
-                                                const QString &supportedAbis, const KeyValuePairList &extra)
+                                                const QString &cPath, const QString &cppPath,
+                                                const QString &abi, const QString &supportedAbis,
+                                                const KeyValuePairList &extra)
 {
     // Sanity check: Does the Id already exist?
     if (exists(map, id)) {
@@ -251,7 +265,8 @@ QVariantMap AddToolChainOperation::addToolChain(const QVariantMap &map,
     data << KeyValuePair(QStringList() << tc << QLatin1String(ID), QVariant(id));
     data << KeyValuePair(QStringList() << tc << QLatin1String(DISPLAYNAME), QVariant(uniqueName));
     data << KeyValuePair(QStringList() << tc << QLatin1String(AUTODETECTED), QVariant(true));
-    data << KeyValuePair(QStringList() << tc << QLatin1String(PATH), QVariant(path));
+    data << KeyValuePair(QStringList() << tc << QLatin1String(CPATH), QVariant(cPath));
+    data << KeyValuePair(QStringList() << tc << QLatin1String(CPPPATH), QVariant(cppPath));
     data << KeyValuePair(QStringList() << tc << QLatin1String(TARGET_ABI), QVariant(abi));
     QVariantList abis;
     QStringList abiStrings = supportedAbis.split(QLatin1Char(','));
diff --git a/src/tools/sdktool/addtoolchainoperation.h b/src/tools/sdktool/addtoolchainoperation.h
index 2f642c8..7bea2d0 100644
--- a/src/tools/sdktool/addtoolchainoperation.h
+++ b/src/tools/sdktool/addtoolchainoperation.h
@@ -46,8 +46,8 @@ public:
 
     static QVariantMap addToolChain(const QVariantMap &map,
                                     const QString &id, const QString &displayName,
-                                    const QString &path, const QString &abi,
-                                    const QString &supportedAbis,
+                                    const QString &cPath, const QString &cppPath,
+                                    const QString &abi, const QString &supportedAbis,
                                     const KeyValuePairList &extra);
 
     static QVariantMap initializeToolChains();
@@ -57,7 +57,8 @@ public:
 private:
     QString m_id;
     QString m_displayName;
-    QString m_path;
+    QString m_cPath;
+    QString m_cppPath;
     QString m_targetAbi;
     QString m_supportedAbis;
     KeyValuePairList m_extra;
diff --git a/src/tools/sdktool/rmkitoperation.cpp b/src/tools/sdktool/rmkitoperation.cpp
index d2c7dc8..a7a509e 100644
--- a/src/tools/sdktool/rmkitoperation.cpp
+++ b/src/tools/sdktool/rmkitoperation.cpp
@@ -100,6 +100,7 @@ bool RmKitOperation::test() const
     QVariantMap tcMap = AddToolChainOperation::initializeToolChains();
     tcMap = AddToolChainOperation::addToolChain(tcMap, QLatin1String("{tc-id}"), QLatin1String("TC"),
                                                 QLatin1String("/usr/bin/gcc"),
+                                                QLatin1String("/usr/bin/g++"),
                                                 QLatin1String("x86-linux-generic-elf-32bit"),
                                                 QLatin1String("x86-linux-generic-elf-32bit"),
                                                 KeyValuePairList());
diff --git a/src/tools/sdktool/rmtoolchainoperation.cpp b/src/tools/sdktool/rmtoolchainoperation.cpp
index 3610ec5..af02750 100644
--- a/src/tools/sdktool/rmtoolchainoperation.cpp
+++ b/src/tools/sdktool/rmtoolchainoperation.cpp
@@ -97,11 +97,11 @@ bool RmToolChainOperation::test() const
 {
     // Add toolchain:
     QVariantMap map = AddToolChainOperation::initializeToolChains();
-    map = AddToolChainOperation::addToolChain(map, QLatin1String("testId"), QLatin1String("name"), QLatin1String("/tmp/test"),
-                                              QLatin1String("test-abi"), QLatin1String("test-abi,test-abi2"),
+    map = AddToolChainOperation::addToolChain(map, QLatin1String("testId"), QLatin1String("name"), QLatin1String("/tmp/test/c"),
+                                              QLatin1String("/tmp/test/c++"), QLatin1String("test-abi"), QLatin1String("test-abi,test-abi2"),
                                               KeyValuePairList() << KeyValuePair(QLatin1String("ExtraKey"), QVariant(QLatin1String("ExtraValue"))));
-    map = AddToolChainOperation::addToolChain(map, QLatin1String("testId2"), QLatin1String("other name"), QLatin1String("/tmp/test2"),
-                                              QLatin1String("test-abi"), QLatin1String("test-abi,test-abi2"),
+    map = AddToolChainOperation::addToolChain(map, QLatin1String("testId2"), QLatin1String("other name"), QLatin1String("/tmp/test2/c"),
+                                              QLatin1String("/tmp/test2/c++"), QLatin1String("test-abi"), QLatin1String("test-abi,test-abi2"),
                                               KeyValuePairList());
 
     QVariantMap result = rmToolChain(QVariantMap(), QLatin1String("nonexistant"));
-- 
2.9.0

