This code injects an LLVM modulemap for glibc and libstdc++ by overriding specific VFS paths. In order to do that, it needs to know the actual locations of glibc and libstdc++, but it only searches `-sysroot` and fails. Here we patch it to also consider `-idirafter` and `-isystem` as added by cc-wrapper. --- a/lib/ClangImporter/ClangIncludePaths.cpp +++ b/lib/ClangImporter/ClangIncludePaths.cpp @@ -142,6 +142,7 @@ /// \return a path without dots (`../`, './'). static llvm::Optional findFirstIncludeDir( const llvm::opt::InputArgList &args, + const llvm::opt::ArgList &DriverArgs, const ArrayRef expectedFileNames, const llvm::IntrusiveRefCntPtr &vfs) { // C++ stdlib paths are added as `-internal-isystem`. @@ -151,6 +152,14 @@ llvm::append_range(includeDirs, args.getAllArgValues( clang::driver::options::OPT_internal_externc_isystem)); + // Nix adds the C stdlib include path using `-idirafter`. + llvm::append_range(includeDirs, + DriverArgs.getAllArgValues( + clang::driver::options::OPT_idirafter)); + // Nix adds the C++ stdlib include path using `-isystem`. + llvm::append_range(includeDirs, + DriverArgs.getAllArgValues( + clang::driver::options::OPT_isystem)); for (const auto &includeDir : includeDirs) { Path dir(includeDir); @@ -218,7 +227,7 @@ // modulemap are present. Path glibcDir; if (auto dir = findFirstIncludeDir( - parsedIncludeArgs, {"inttypes.h", "unistd.h", "stdint.h"}, vfs)) { + parsedIncludeArgs, clangDriverArgs, {"inttypes.h", "unistd.h", "stdint.h"}, vfs)) { glibcDir = dir.value(); } else { ctx.Diags.diagnose(SourceLoc(), diag::glibc_not_found, triple.str()); @@ -276,7 +285,7 @@ auto parsedStdlibArgs = parseClangDriverArgs(clangDriver, stdlibArgStrings); Path cxxStdlibDir; - if (auto dir = findFirstIncludeDir(parsedStdlibArgs, + if (auto dir = findFirstIncludeDir(parsedStdlibArgs, clangDriverArgs, {"cstdlib", "string", "vector"}, vfs)) { cxxStdlibDir = dir.value(); } else {