Clang: Avoid consuming gcc internal include paths

Given the (default) include paths of GCC, e.g.

 /usr/include/c++/7
 /usr/include/x86_64-linux-gnu/c++/7
 /usr/include/c++/7/backward
 /usr/lib/gcc/x86_64-linux-gnu/7/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/7/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include

discard gcc-internal paths like /usr/lib/gcc/x86_64-linux-gnu/7/include
as they are not relevant for clang and even confuse it with regard to
 #include_next.

Paths below the gcc install dir are considered as gcc-internal. The
install dir is queried with

  $ gcc -print-search-dirs

Some GCC distributions, like MinGW, ship the standard library headers in
the install dir. Ensure to not discard these.

Fixes: QTCREATORBUG-22898
Change-Id: Ia85258fb01b72ad073e71390e003fe8268e3b01f
Reviewed-by: Cristian Adam <cristian.adam@qt.io>
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
Nikolai Kosjar
2019-10-10 11:04:01 +02:00
parent 7a87dc0484
commit 5165c037eb
12 changed files with 137 additions and 0 deletions

View File

@@ -529,6 +529,7 @@ void Dumper::dumpProjectInfos( const QList<ProjectInfo> &projectInfos)
m_out << i3 << "ToolChain Type : " << part->toolchainType.toString() << "\n";
m_out << i3 << "ToolChain Target Triple: " << part->toolChainTargetTriple << "\n";
m_out << i3 << "ToolChain Word Width : " << part->toolChainWordWidth << "\n";
m_out << i3 << "ToolChain Install Dir : " << part->toolChainInstallDir << "\n";
m_out << i3 << "Compiler Flags : " << part->compilerFlags.join(", ") << "\n";
m_out << i3 << "Selected For Building : " << part->selectedForBuilding << "\n";
m_out << i3 << "Build System Target : " << part->buildSystemTarget << "\n";

View File

@@ -167,6 +167,7 @@ ProjectPart::Ptr ProjectInfoGenerator::createProjectPart(
part->isMsvc2015Toolchain = tcInfo.isMsvc2015ToolChain;
part->toolChainWordWidth = tcInfo.wordWidth == 64 ? ProjectPart::WordWidth64Bit
: ProjectPart::WordWidth32Bit;
part->toolChainInstallDir = tcInfo.installDir;
part->toolChainTargetTriple = tcInfo.targetTriple;
part->extraCodeModelFlags = tcInfo.extraCodeModelFlags;
part->compilerFlags = flags.commandLineFlags;

View File

@@ -30,9 +30,12 @@
#endif
#include <projectexplorer/project.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <QRegularExpression>
#include <utils/algorithm.h>
namespace CppTools {
using ProjectExplorer::HeaderPath;
@@ -57,6 +60,31 @@ bool HeaderPathFilter::isProjectHeaderPath(const QString &path) const
return path.startsWith(projectDirectory) || path.startsWith(buildDirectory);
}
void HeaderPathFilter::removeGccInternalIncludePaths()
{
if (projectPart.toolchainType != ProjectExplorer::Constants::GCC_TOOLCHAIN_TYPEID
&& projectPart.toolchainType != ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID) {
return;
}
if (projectPart.toolChainInstallDir.isEmpty())
return;
const Utils::FilePath gccInstallDir = projectPart.toolChainInstallDir;
auto isGccInternalInclude = [gccInstallDir](const HeaderPath &headerPath){
const auto includePath = Utils::FilePath::fromString(headerPath.path);
if (includePath.isChildOf(gccInstallDir)) {
const QString remainingPath = headerPath.path.mid(gccInstallDir.toString().size());
// MinGW ships the standard library headers in "<installdir>/include/c++".
// Ensure that we do not remove include paths pointing there.
return !remainingPath.startsWith("/include/c++");
}
return false;
};
Utils::erase(builtInHeaderPaths, isGccInternalInclude);
}
void HeaderPathFilter::filterHeaderPath(const ProjectExplorer::HeaderPath &headerPath)
{
if (headerPath.path.isEmpty())
@@ -135,6 +163,7 @@ void removeClangSystemHeaderPaths(HeaderPaths &headerPaths)
void HeaderPathFilter::tweakHeaderPaths()
{
removeClangSystemHeaderPaths(builtInHeaderPaths);
removeGccInternalIncludePaths();
auto split = resourceIterator(builtInHeaderPaths,
projectPart.toolChainTargetTriple.contains("darwin"));

View File

@@ -57,6 +57,8 @@ private:
bool isProjectHeaderPath(const QString &path) const;
void removeGccInternalIncludePaths();
static QString ensurePathWithSlashEnding(const QString &path);
public:

View File

@@ -42,6 +42,7 @@
#include <cplusplus/Token.h>
#include <utils/cpplanguage_details.h>
#include <utils/fileutils.h>
#include <QString>
#include <QSharedPointer>
@@ -108,6 +109,7 @@ public:
bool isMsvc2015Toolchain = false;
QString toolChainTargetTriple;
ToolChainWordWidth toolChainWordWidth = WordWidth32Bit;
Utils::FilePath toolChainInstallDir;
ProjectExplorer::WarningFlags warningFlags = ProjectExplorer::WarningFlags::Default;
// Misc