diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1812,6 +1812,122 @@ return Driver::GetResourcesPath(ClangExecutable, CLANG_RESOURCE_DIR); } +static void GenerateHeaderSearchArgs(const HeaderSearchOptions &Opts, + SmallVectorImpl &Args, + CompilerInvocation::StringAllocator SA) { + const OptTable &OptTable = getDriverOptTable(); + + std::string Dash("-"); + std::string OptName; + + if (Opts.UseLibcxx) { + OptName = Dash + OptTable.getOptionName(OPT_stdlib_EQ); + Args.emplace_back(SA(OptName + "libc++")); + } + + if (!Opts.ModuleCachePath.empty()) { + OptName = Dash + OptTable.getOptionName(OPT_fmodules_cache_path); + Args.emplace_back(SA(OptName + Opts.ModuleCachePath)); + } + + OptName = Dash + OptTable.getOptionName(OPT_fmodule_file); + for (const auto &File : Opts.PrebuiltModuleFiles) + Args.emplace_back(SA(OptName + File.first + "=" + File.second)); + + OptName = Dash + OptTable.getOptionName(OPT_fprebuilt_module_path); + for (const auto &Path : Opts.PrebuiltModulePaths) + Args.emplace_back(SA(OptName + Path)); + + OptName = Dash + OptTable.getOptionName(OPT_fmodules_ignore_macro); + for (const auto &Macro : Opts.ModulesIgnoreMacros) + Args.emplace_back(SA(OptName + Macro.val())); + + auto matches = [](const HeaderSearchOptions::Entry &Entry, + frontend::IncludeDirGroup Group, bool IsFramework, + bool IgnoreSysRoot) { + return Entry.Group == Group && Entry.IsFramework == IsFramework && + Entry.IgnoreSysRoot == IgnoreSysRoot; + }; + + for (const HeaderSearchOptions::Entry &E : Opts.UserEntries) { + Optional Opt; + + // Add -I..., -F..., and -index-header-map options in order. + + if (E.Group == frontend::IndexHeaderMap) { + OptName = OptTable.getOptionName(OPT_index_header_map); + Args.emplace_back(SA(OptName)); + } + + if (matches(E, frontend::IndexHeaderMap, true, true)) + Opt = OPT_F; + else if (matches(E, frontend::IndexHeaderMap, false, true)) + Opt = OPT_I; + else if (matches(E, frontend::Angled, true, true)) + Opt = OPT_F; + else if (matches(E, frontend::Angled, false, true)) + // Also handles [-iprefix=xx] -iwithprefixbefore=yy as -I[xx]yy. + Opt = OPT_I; + + if (Opt) { + OptName = Dash + OptTable.getOptionName(*Opt); + Args.emplace_back(SA(OptName + E.Path)); + continue; + } + + if (matches(E, frontend::After, false, true)) + // Also handles [-iprefix=xx] -iwithprefix=yy as -idirafter=[xx]yy. + Opt = OPT_idirafter; + else if (matches(E, frontend::Quoted, false, true)) + Opt = OPT_iquote; + else if (matches(E, frontend::System, false, true)) + Opt = OPT_isystem; + else if (matches(E, frontend::System, false, false)) + Opt = OPT_iwithsysroot; + else if (matches(E, frontend::System, true, true)) + Opt = OPT_iframework; + else if (matches(E, frontend::System, true, false)) + Opt = OPT_iframeworkwithsysroot; + + else if (matches(E, frontend::CSystem, false, true)) + // Add the paths for the various language specific isystem flags. + Opt = OPT_c_isystem; + else if (matches(E, frontend::CXXSystem, false, true)) + Opt = OPT_cxx_isystem; + else if (matches(E, frontend::ObjCSystem, false, true)) + Opt = OPT_objc_isystem; + else if (matches(E, frontend::ObjCXXSystem, false, true)) + Opt = OPT_objcxx_isystem; + + else if (matches(E, frontend::System, false, true)) + // Add the internal paths from a driver that detects standard include + // paths. + Opt = OPT_internal_isystem; + else if (matches(E, frontend::ExternCSystem, false, true)) + Opt = OPT_internal_externc_isystem; + else + llvm_unreachable("Tried to marshall invalid HeaderSearchOptions::Entry"); + + OptName = Dash + OptTable.getOptionName(*Opt); + Args.emplace_back(SA(OptName)); + Args.emplace_back(SA(E.Path)); + } + + // Add the path prefixes which are implicitly treated as being system headers. + for (const auto &P : Opts.SystemHeaderPrefixes) { + OptSpecifier Opt = P.IsSystemHeader ? OPT_system_header_prefix + : OPT_no_system_header_prefix; + OptName = Dash + Dash + OptTable.getOptionName(Opt); + Args.emplace_back(SA(OptName + P.Prefix)); + } + + for (const std::string &F : Opts.VFSOverlayFiles) { + OptName = Dash + OptTable.getOptionName(OPT_ivfsoverlay); + Args.emplace_back(SA(OptName)); + Args.emplace_back(F.c_str()); + } +} + static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args, const std::string &WorkingDir) { if (const Arg *A = Args.getLastArg(OPT_stdlib_EQ)) @@ -3215,6 +3331,8 @@ #undef DIAG_OPTION_WITH_MARSHALLING #undef OPTION_WITH_MARSHALLING #undef GENERATE_OPTION_WITH_MARSHALLING + + GenerateHeaderSearchArgs(getHeaderSearchOpts(), Args, SA); } IntrusiveRefCntPtr