Index: include/clang/Driver/Multilib.h =================================================================== --- include/clang/Driver/Multilib.h +++ include/clang/Driver/Multilib.h @@ -97,6 +97,10 @@ typedef multilib_list::iterator iterator; typedef multilib_list::const_iterator const_iterator; + typedef std::function( + StringRef InstallDir, StringRef Triple, const Multilib &M)> + IncludeDirsFunc; + struct FilterCallback { virtual ~FilterCallback() {}; /// \return true iff the filter should remove the Multilib from the set @@ -105,6 +109,7 @@ private: multilib_list Multilibs; + IncludeDirsFunc IncludeCallback; public: MultilibSet() {} @@ -150,6 +155,12 @@ void print(raw_ostream &OS) const; + MultilibSet &includeDirsCallback(IncludeDirsFunc F) { + IncludeCallback = F; + return *this; + } + IncludeDirsFunc includeDirsCallback() const { return IncludeCallback; } + private: /// Apply the filter to Multilibs and return the subset that remains static multilib_list filterCopy(const FilterCallback &F, Index: lib/Driver/ToolChains.cpp =================================================================== --- lib/Driver/ToolChains.cpp +++ lib/Driver/ToolChains.cpp @@ -1726,7 +1726,14 @@ .Maybe(SoftFloat) .Maybe(Nan2008) .FilterOut(".*sof/nan2008") - .FilterOut(NonExistent); + .FilterOut(NonExistent) + .includeDirsCallback([]( + StringRef InstallDir, StringRef TripleStr, const Multilib &M) { + std::vector Dirs; + Dirs.push_back((InstallDir + "/include").str()); + Dirs.push_back((InstallDir + "/../../../../sysroot/usr/include").str()); + return Dirs; + }); } // Check for Code Sourcery toolchain multilibs @@ -1771,7 +1778,15 @@ .Maybe(MAbi64) .FilterOut("/mips16.*/64") .FilterOut("/micromips.*/64") - .FilterOut(NonExistent); + .FilterOut(NonExistent) + .includeDirsCallback([]( + StringRef InstallDir, StringRef TripleStr, const Multilib &M) { + std::vector Dirs; + Dirs.push_back((InstallDir + "/include").str()); + Dirs.push_back((InstallDir + "/../../../../" + TripleStr + + "/libc/usr/include").str()); + return Dirs; + }); } MultilibSet AndroidMipsMultilibs = MultilibSet() @@ -1813,7 +1828,14 @@ .Maybe(Mips64r6) .Maybe(MAbi64) .Maybe(LittleEndian) - .FilterOut(NonExistent); + .FilterOut(NonExistent) + .includeDirsCallback([]( + StringRef InstallDir, StringRef TripleStr, const Multilib &M) { + std::vector Dirs; + Dirs.push_back((InstallDir + "/include").str()); + Dirs.push_back((InstallDir + "/../../../../sysroot/usr/include").str()); + return Dirs; + }); } StringRef CPUName; @@ -3215,20 +3237,16 @@ // Lacking those, try to detect the correct set of system includes for the // target triple. - // Sourcery CodeBench and modern FSF Mips toolchains put extern C - // system includes under three additional directories. - if (GCCInstallation.isValid() && isMipsArch(getTriple().getArch())) { - addExternCSystemIncludeIfExists( - DriverArgs, CC1Args, GCCInstallation.getInstallPath() + "/include"); - - addExternCSystemIncludeIfExists( - DriverArgs, CC1Args, - GCCInstallation.getInstallPath() + "/../../../../" + - GCCInstallation.getTriple().str() + "/libc/usr/include"); - - addExternCSystemIncludeIfExists( - DriverArgs, CC1Args, - GCCInstallation.getInstallPath() + "/../../../../sysroot/usr/include"); + // Add include directories specific to the selected multilib set and multilib. + if (GCCInstallation.isValid()) { + auto Callback = Multilibs.includeDirsCallback(); + if (Callback) { + const auto IncludePaths = Callback(GCCInstallation.getInstallPath(), + GCCInstallation.getTriple().str(), + GCCInstallation.getMultilib()); + for (const auto &Path : IncludePaths) + addExternCSystemIncludeIfExists(DriverArgs, CC1Args, Path); + } } // Implement generic Debian multiarch support.