1*04eeddc0SDimitry Andric //===--- InitHeaderSearch.cpp - Initialize header search paths ------------===// 2*04eeddc0SDimitry Andric // 3*04eeddc0SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*04eeddc0SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*04eeddc0SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*04eeddc0SDimitry Andric // 7*04eeddc0SDimitry Andric //===----------------------------------------------------------------------===// 8*04eeddc0SDimitry Andric // 9*04eeddc0SDimitry Andric // This file implements the InitHeaderSearch class. 10*04eeddc0SDimitry Andric // 11*04eeddc0SDimitry Andric //===----------------------------------------------------------------------===// 12*04eeddc0SDimitry Andric 13*04eeddc0SDimitry Andric #include "clang/Basic/DiagnosticFrontend.h" 14*04eeddc0SDimitry Andric #include "clang/Basic/FileManager.h" 15*04eeddc0SDimitry Andric #include "clang/Basic/LangOptions.h" 16*04eeddc0SDimitry Andric #include "clang/Config/config.h" // C_INCLUDE_DIRS 17*04eeddc0SDimitry Andric #include "clang/Lex/HeaderMap.h" 18*04eeddc0SDimitry Andric #include "clang/Lex/HeaderSearch.h" 19*04eeddc0SDimitry Andric #include "clang/Lex/HeaderSearchOptions.h" 20*04eeddc0SDimitry Andric #include "llvm/ADT/SmallPtrSet.h" 21*04eeddc0SDimitry Andric #include "llvm/ADT/SmallString.h" 22*04eeddc0SDimitry Andric #include "llvm/ADT/SmallVector.h" 23*04eeddc0SDimitry Andric #include "llvm/ADT/StringExtras.h" 24*04eeddc0SDimitry Andric #include "llvm/ADT/Triple.h" 25*04eeddc0SDimitry Andric #include "llvm/ADT/Twine.h" 26*04eeddc0SDimitry Andric #include "llvm/Support/ErrorHandling.h" 27*04eeddc0SDimitry Andric #include "llvm/Support/Path.h" 28*04eeddc0SDimitry Andric #include "llvm/Support/raw_ostream.h" 29*04eeddc0SDimitry Andric 30*04eeddc0SDimitry Andric using namespace clang; 31*04eeddc0SDimitry Andric using namespace clang::frontend; 32*04eeddc0SDimitry Andric 33*04eeddc0SDimitry Andric namespace { 34*04eeddc0SDimitry Andric /// Holds information about a single DirectoryLookup object. 35*04eeddc0SDimitry Andric struct DirectoryLookupInfo { 36*04eeddc0SDimitry Andric IncludeDirGroup Group; 37*04eeddc0SDimitry Andric DirectoryLookup Lookup; 38*04eeddc0SDimitry Andric Optional<unsigned> UserEntryIdx; 39*04eeddc0SDimitry Andric 40*04eeddc0SDimitry Andric DirectoryLookupInfo(IncludeDirGroup Group, DirectoryLookup Lookup, 41*04eeddc0SDimitry Andric Optional<unsigned> UserEntryIdx) 42*04eeddc0SDimitry Andric : Group(Group), Lookup(Lookup), UserEntryIdx(UserEntryIdx) {} 43*04eeddc0SDimitry Andric }; 44*04eeddc0SDimitry Andric 45*04eeddc0SDimitry Andric /// InitHeaderSearch - This class makes it easier to set the search paths of 46*04eeddc0SDimitry Andric /// a HeaderSearch object. InitHeaderSearch stores several search path lists 47*04eeddc0SDimitry Andric /// internally, which can be sent to a HeaderSearch object in one swoop. 48*04eeddc0SDimitry Andric class InitHeaderSearch { 49*04eeddc0SDimitry Andric std::vector<DirectoryLookupInfo> IncludePath; 50*04eeddc0SDimitry Andric std::vector<std::pair<std::string, bool> > SystemHeaderPrefixes; 51*04eeddc0SDimitry Andric HeaderSearch &Headers; 52*04eeddc0SDimitry Andric bool Verbose; 53*04eeddc0SDimitry Andric std::string IncludeSysroot; 54*04eeddc0SDimitry Andric bool HasSysroot; 55*04eeddc0SDimitry Andric 56*04eeddc0SDimitry Andric public: 57*04eeddc0SDimitry Andric InitHeaderSearch(HeaderSearch &HS, bool verbose, StringRef sysroot) 58*04eeddc0SDimitry Andric : Headers(HS), Verbose(verbose), IncludeSysroot(std::string(sysroot)), 59*04eeddc0SDimitry Andric HasSysroot(!(sysroot.empty() || sysroot == "/")) {} 60*04eeddc0SDimitry Andric 61*04eeddc0SDimitry Andric /// AddPath - Add the specified path to the specified group list, prefixing 62*04eeddc0SDimitry Andric /// the sysroot if used. 63*04eeddc0SDimitry Andric /// Returns true if the path exists, false if it was ignored. 64*04eeddc0SDimitry Andric bool AddPath(const Twine &Path, IncludeDirGroup Group, bool isFramework, 65*04eeddc0SDimitry Andric Optional<unsigned> UserEntryIdx = None); 66*04eeddc0SDimitry Andric 67*04eeddc0SDimitry Andric /// AddUnmappedPath - Add the specified path to the specified group list, 68*04eeddc0SDimitry Andric /// without performing any sysroot remapping. 69*04eeddc0SDimitry Andric /// Returns true if the path exists, false if it was ignored. 70*04eeddc0SDimitry Andric bool AddUnmappedPath(const Twine &Path, IncludeDirGroup Group, 71*04eeddc0SDimitry Andric bool isFramework, 72*04eeddc0SDimitry Andric Optional<unsigned> UserEntryIdx = None); 73*04eeddc0SDimitry Andric 74*04eeddc0SDimitry Andric /// AddSystemHeaderPrefix - Add the specified prefix to the system header 75*04eeddc0SDimitry Andric /// prefix list. 76*04eeddc0SDimitry Andric void AddSystemHeaderPrefix(StringRef Prefix, bool IsSystemHeader) { 77*04eeddc0SDimitry Andric SystemHeaderPrefixes.emplace_back(std::string(Prefix), IsSystemHeader); 78*04eeddc0SDimitry Andric } 79*04eeddc0SDimitry Andric 80*04eeddc0SDimitry Andric /// AddGnuCPlusPlusIncludePaths - Add the necessary paths to support a gnu 81*04eeddc0SDimitry Andric /// libstdc++. 82*04eeddc0SDimitry Andric /// Returns true if the \p Base path was found, false if it does not exist. 83*04eeddc0SDimitry Andric bool AddGnuCPlusPlusIncludePaths(StringRef Base, StringRef ArchDir, 84*04eeddc0SDimitry Andric StringRef Dir32, StringRef Dir64, 85*04eeddc0SDimitry Andric const llvm::Triple &triple); 86*04eeddc0SDimitry Andric 87*04eeddc0SDimitry Andric /// AddMinGWCPlusPlusIncludePaths - Add the necessary paths to support a MinGW 88*04eeddc0SDimitry Andric /// libstdc++. 89*04eeddc0SDimitry Andric void AddMinGWCPlusPlusIncludePaths(StringRef Base, 90*04eeddc0SDimitry Andric StringRef Arch, 91*04eeddc0SDimitry Andric StringRef Version); 92*04eeddc0SDimitry Andric 93*04eeddc0SDimitry Andric // AddDefaultCIncludePaths - Add paths that should always be searched. 94*04eeddc0SDimitry Andric void AddDefaultCIncludePaths(const llvm::Triple &triple, 95*04eeddc0SDimitry Andric const HeaderSearchOptions &HSOpts); 96*04eeddc0SDimitry Andric 97*04eeddc0SDimitry Andric // AddDefaultCPlusPlusIncludePaths - Add paths that should be searched when 98*04eeddc0SDimitry Andric // compiling c++. 99*04eeddc0SDimitry Andric void AddDefaultCPlusPlusIncludePaths(const LangOptions &LangOpts, 100*04eeddc0SDimitry Andric const llvm::Triple &triple, 101*04eeddc0SDimitry Andric const HeaderSearchOptions &HSOpts); 102*04eeddc0SDimitry Andric 103*04eeddc0SDimitry Andric /// AddDefaultSystemIncludePaths - Adds the default system include paths so 104*04eeddc0SDimitry Andric /// that e.g. stdio.h is found. 105*04eeddc0SDimitry Andric void AddDefaultIncludePaths(const LangOptions &Lang, 106*04eeddc0SDimitry Andric const llvm::Triple &triple, 107*04eeddc0SDimitry Andric const HeaderSearchOptions &HSOpts); 108*04eeddc0SDimitry Andric 109*04eeddc0SDimitry Andric /// Realize - Merges all search path lists into one list and send it to 110*04eeddc0SDimitry Andric /// HeaderSearch. 111*04eeddc0SDimitry Andric void Realize(const LangOptions &Lang); 112*04eeddc0SDimitry Andric }; 113*04eeddc0SDimitry Andric 114*04eeddc0SDimitry Andric } // end anonymous namespace. 115*04eeddc0SDimitry Andric 116*04eeddc0SDimitry Andric static bool CanPrefixSysroot(StringRef Path) { 117*04eeddc0SDimitry Andric #if defined(_WIN32) 118*04eeddc0SDimitry Andric return !Path.empty() && llvm::sys::path::is_separator(Path[0]); 119*04eeddc0SDimitry Andric #else 120*04eeddc0SDimitry Andric return llvm::sys::path::is_absolute(Path); 121*04eeddc0SDimitry Andric #endif 122*04eeddc0SDimitry Andric } 123*04eeddc0SDimitry Andric 124*04eeddc0SDimitry Andric bool InitHeaderSearch::AddPath(const Twine &Path, IncludeDirGroup Group, 125*04eeddc0SDimitry Andric bool isFramework, 126*04eeddc0SDimitry Andric Optional<unsigned> UserEntryIdx) { 127*04eeddc0SDimitry Andric // Add the path with sysroot prepended, if desired and this is a system header 128*04eeddc0SDimitry Andric // group. 129*04eeddc0SDimitry Andric if (HasSysroot) { 130*04eeddc0SDimitry Andric SmallString<256> MappedPathStorage; 131*04eeddc0SDimitry Andric StringRef MappedPathStr = Path.toStringRef(MappedPathStorage); 132*04eeddc0SDimitry Andric if (CanPrefixSysroot(MappedPathStr)) { 133*04eeddc0SDimitry Andric return AddUnmappedPath(IncludeSysroot + Path, Group, isFramework, 134*04eeddc0SDimitry Andric UserEntryIdx); 135*04eeddc0SDimitry Andric } 136*04eeddc0SDimitry Andric } 137*04eeddc0SDimitry Andric 138*04eeddc0SDimitry Andric return AddUnmappedPath(Path, Group, isFramework, UserEntryIdx); 139*04eeddc0SDimitry Andric } 140*04eeddc0SDimitry Andric 141*04eeddc0SDimitry Andric bool InitHeaderSearch::AddUnmappedPath(const Twine &Path, IncludeDirGroup Group, 142*04eeddc0SDimitry Andric bool isFramework, 143*04eeddc0SDimitry Andric Optional<unsigned> UserEntryIdx) { 144*04eeddc0SDimitry Andric assert(!Path.isTriviallyEmpty() && "can't handle empty path here"); 145*04eeddc0SDimitry Andric 146*04eeddc0SDimitry Andric FileManager &FM = Headers.getFileMgr(); 147*04eeddc0SDimitry Andric SmallString<256> MappedPathStorage; 148*04eeddc0SDimitry Andric StringRef MappedPathStr = Path.toStringRef(MappedPathStorage); 149*04eeddc0SDimitry Andric 150*04eeddc0SDimitry Andric // If use system headers while cross-compiling, emit the warning. 151*04eeddc0SDimitry Andric if (HasSysroot && (MappedPathStr.startswith("/usr/include") || 152*04eeddc0SDimitry Andric MappedPathStr.startswith("/usr/local/include"))) { 153*04eeddc0SDimitry Andric Headers.getDiags().Report(diag::warn_poison_system_directories) 154*04eeddc0SDimitry Andric << MappedPathStr; 155*04eeddc0SDimitry Andric } 156*04eeddc0SDimitry Andric 157*04eeddc0SDimitry Andric // Compute the DirectoryLookup type. 158*04eeddc0SDimitry Andric SrcMgr::CharacteristicKind Type; 159*04eeddc0SDimitry Andric if (Group == Quoted || Group == Angled || Group == IndexHeaderMap) { 160*04eeddc0SDimitry Andric Type = SrcMgr::C_User; 161*04eeddc0SDimitry Andric } else if (Group == ExternCSystem) { 162*04eeddc0SDimitry Andric Type = SrcMgr::C_ExternCSystem; 163*04eeddc0SDimitry Andric } else { 164*04eeddc0SDimitry Andric Type = SrcMgr::C_System; 165*04eeddc0SDimitry Andric } 166*04eeddc0SDimitry Andric 167*04eeddc0SDimitry Andric // If the directory exists, add it. 168*04eeddc0SDimitry Andric if (auto DE = FM.getOptionalDirectoryRef(MappedPathStr)) { 169*04eeddc0SDimitry Andric IncludePath.emplace_back(Group, DirectoryLookup(*DE, Type, isFramework), 170*04eeddc0SDimitry Andric UserEntryIdx); 171*04eeddc0SDimitry Andric return true; 172*04eeddc0SDimitry Andric } 173*04eeddc0SDimitry Andric 174*04eeddc0SDimitry Andric // Check to see if this is an apple-style headermap (which are not allowed to 175*04eeddc0SDimitry Andric // be frameworks). 176*04eeddc0SDimitry Andric if (!isFramework) { 177*04eeddc0SDimitry Andric if (auto FE = FM.getFile(MappedPathStr)) { 178*04eeddc0SDimitry Andric if (const HeaderMap *HM = Headers.CreateHeaderMap(*FE)) { 179*04eeddc0SDimitry Andric // It is a headermap, add it to the search path. 180*04eeddc0SDimitry Andric IncludePath.emplace_back( 181*04eeddc0SDimitry Andric Group, DirectoryLookup(HM, Type, Group == IndexHeaderMap), 182*04eeddc0SDimitry Andric UserEntryIdx); 183*04eeddc0SDimitry Andric return true; 184*04eeddc0SDimitry Andric } 185*04eeddc0SDimitry Andric } 186*04eeddc0SDimitry Andric } 187*04eeddc0SDimitry Andric 188*04eeddc0SDimitry Andric if (Verbose) 189*04eeddc0SDimitry Andric llvm::errs() << "ignoring nonexistent directory \"" 190*04eeddc0SDimitry Andric << MappedPathStr << "\"\n"; 191*04eeddc0SDimitry Andric return false; 192*04eeddc0SDimitry Andric } 193*04eeddc0SDimitry Andric 194*04eeddc0SDimitry Andric bool InitHeaderSearch::AddGnuCPlusPlusIncludePaths(StringRef Base, 195*04eeddc0SDimitry Andric StringRef ArchDir, 196*04eeddc0SDimitry Andric StringRef Dir32, 197*04eeddc0SDimitry Andric StringRef Dir64, 198*04eeddc0SDimitry Andric const llvm::Triple &triple) { 199*04eeddc0SDimitry Andric // Add the base dir 200*04eeddc0SDimitry Andric bool IsBaseFound = AddPath(Base, CXXSystem, false); 201*04eeddc0SDimitry Andric 202*04eeddc0SDimitry Andric // Add the multilib dirs 203*04eeddc0SDimitry Andric llvm::Triple::ArchType arch = triple.getArch(); 204*04eeddc0SDimitry Andric bool is64bit = arch == llvm::Triple::ppc64 || arch == llvm::Triple::x86_64; 205*04eeddc0SDimitry Andric if (is64bit) 206*04eeddc0SDimitry Andric AddPath(Base + "/" + ArchDir + "/" + Dir64, CXXSystem, false); 207*04eeddc0SDimitry Andric else 208*04eeddc0SDimitry Andric AddPath(Base + "/" + ArchDir + "/" + Dir32, CXXSystem, false); 209*04eeddc0SDimitry Andric 210*04eeddc0SDimitry Andric // Add the backward dir 211*04eeddc0SDimitry Andric AddPath(Base + "/backward", CXXSystem, false); 212*04eeddc0SDimitry Andric return IsBaseFound; 213*04eeddc0SDimitry Andric } 214*04eeddc0SDimitry Andric 215*04eeddc0SDimitry Andric void InitHeaderSearch::AddMinGWCPlusPlusIncludePaths(StringRef Base, 216*04eeddc0SDimitry Andric StringRef Arch, 217*04eeddc0SDimitry Andric StringRef Version) { 218*04eeddc0SDimitry Andric AddPath(Base + "/" + Arch + "/" + Version + "/include/c++", 219*04eeddc0SDimitry Andric CXXSystem, false); 220*04eeddc0SDimitry Andric AddPath(Base + "/" + Arch + "/" + Version + "/include/c++/" + Arch, 221*04eeddc0SDimitry Andric CXXSystem, false); 222*04eeddc0SDimitry Andric AddPath(Base + "/" + Arch + "/" + Version + "/include/c++/backward", 223*04eeddc0SDimitry Andric CXXSystem, false); 224*04eeddc0SDimitry Andric } 225*04eeddc0SDimitry Andric 226*04eeddc0SDimitry Andric void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple, 227*04eeddc0SDimitry Andric const HeaderSearchOptions &HSOpts) { 228*04eeddc0SDimitry Andric llvm::Triple::OSType os = triple.getOS(); 229*04eeddc0SDimitry Andric 230*04eeddc0SDimitry Andric if (triple.isOSDarwin()) { 231*04eeddc0SDimitry Andric llvm_unreachable("Include management is handled in the driver."); 232*04eeddc0SDimitry Andric } 233*04eeddc0SDimitry Andric 234*04eeddc0SDimitry Andric if (HSOpts.UseStandardSystemIncludes) { 235*04eeddc0SDimitry Andric switch (os) { 236*04eeddc0SDimitry Andric case llvm::Triple::CloudABI: 237*04eeddc0SDimitry Andric case llvm::Triple::FreeBSD: 238*04eeddc0SDimitry Andric case llvm::Triple::NetBSD: 239*04eeddc0SDimitry Andric case llvm::Triple::OpenBSD: 240*04eeddc0SDimitry Andric case llvm::Triple::NaCl: 241*04eeddc0SDimitry Andric case llvm::Triple::PS4: 242*04eeddc0SDimitry Andric case llvm::Triple::ELFIAMCU: 243*04eeddc0SDimitry Andric case llvm::Triple::Fuchsia: 244*04eeddc0SDimitry Andric break; 245*04eeddc0SDimitry Andric case llvm::Triple::Win32: 246*04eeddc0SDimitry Andric if (triple.getEnvironment() != llvm::Triple::Cygnus) 247*04eeddc0SDimitry Andric break; 248*04eeddc0SDimitry Andric LLVM_FALLTHROUGH; 249*04eeddc0SDimitry Andric default: 250*04eeddc0SDimitry Andric // FIXME: temporary hack: hard-coded paths. 251*04eeddc0SDimitry Andric AddPath("/usr/local/include", System, false); 252*04eeddc0SDimitry Andric break; 253*04eeddc0SDimitry Andric } 254*04eeddc0SDimitry Andric } 255*04eeddc0SDimitry Andric 256*04eeddc0SDimitry Andric // Builtin includes use #include_next directives and should be positioned 257*04eeddc0SDimitry Andric // just prior C include dirs. 258*04eeddc0SDimitry Andric if (HSOpts.UseBuiltinIncludes) { 259*04eeddc0SDimitry Andric // Ignore the sys root, we *always* look for clang headers relative to 260*04eeddc0SDimitry Andric // supplied path. 261*04eeddc0SDimitry Andric SmallString<128> P = StringRef(HSOpts.ResourceDir); 262*04eeddc0SDimitry Andric llvm::sys::path::append(P, "include"); 263*04eeddc0SDimitry Andric AddUnmappedPath(P, ExternCSystem, false); 264*04eeddc0SDimitry Andric } 265*04eeddc0SDimitry Andric 266*04eeddc0SDimitry Andric // All remaining additions are for system include directories, early exit if 267*04eeddc0SDimitry Andric // we aren't using them. 268*04eeddc0SDimitry Andric if (!HSOpts.UseStandardSystemIncludes) 269*04eeddc0SDimitry Andric return; 270*04eeddc0SDimitry Andric 271*04eeddc0SDimitry Andric // Add dirs specified via 'configure --with-c-include-dirs'. 272*04eeddc0SDimitry Andric StringRef CIncludeDirs(C_INCLUDE_DIRS); 273*04eeddc0SDimitry Andric if (CIncludeDirs != "") { 274*04eeddc0SDimitry Andric SmallVector<StringRef, 5> dirs; 275*04eeddc0SDimitry Andric CIncludeDirs.split(dirs, ":"); 276*04eeddc0SDimitry Andric for (StringRef dir : dirs) 277*04eeddc0SDimitry Andric AddPath(dir, ExternCSystem, false); 278*04eeddc0SDimitry Andric return; 279*04eeddc0SDimitry Andric } 280*04eeddc0SDimitry Andric 281*04eeddc0SDimitry Andric switch (os) { 282*04eeddc0SDimitry Andric case llvm::Triple::Linux: 283*04eeddc0SDimitry Andric case llvm::Triple::Hurd: 284*04eeddc0SDimitry Andric case llvm::Triple::Solaris: 285*04eeddc0SDimitry Andric case llvm::Triple::OpenBSD: 286*04eeddc0SDimitry Andric llvm_unreachable("Include management is handled in the driver."); 287*04eeddc0SDimitry Andric 288*04eeddc0SDimitry Andric case llvm::Triple::CloudABI: { 289*04eeddc0SDimitry Andric // <sysroot>/<triple>/include 290*04eeddc0SDimitry Andric SmallString<128> P = StringRef(HSOpts.ResourceDir); 291*04eeddc0SDimitry Andric llvm::sys::path::append(P, "../../..", triple.str(), "include"); 292*04eeddc0SDimitry Andric AddPath(P, System, false); 293*04eeddc0SDimitry Andric break; 294*04eeddc0SDimitry Andric } 295*04eeddc0SDimitry Andric 296*04eeddc0SDimitry Andric case llvm::Triple::Haiku: 297*04eeddc0SDimitry Andric AddPath("/boot/system/non-packaged/develop/headers", System, false); 298*04eeddc0SDimitry Andric AddPath("/boot/system/develop/headers/os", System, false); 299*04eeddc0SDimitry Andric AddPath("/boot/system/develop/headers/os/app", System, false); 300*04eeddc0SDimitry Andric AddPath("/boot/system/develop/headers/os/arch", System, false); 301*04eeddc0SDimitry Andric AddPath("/boot/system/develop/headers/os/device", System, false); 302*04eeddc0SDimitry Andric AddPath("/boot/system/develop/headers/os/drivers", System, false); 303*04eeddc0SDimitry Andric AddPath("/boot/system/develop/headers/os/game", System, false); 304*04eeddc0SDimitry Andric AddPath("/boot/system/develop/headers/os/interface", System, false); 305*04eeddc0SDimitry Andric AddPath("/boot/system/develop/headers/os/kernel", System, false); 306*04eeddc0SDimitry Andric AddPath("/boot/system/develop/headers/os/locale", System, false); 307*04eeddc0SDimitry Andric AddPath("/boot/system/develop/headers/os/mail", System, false); 308*04eeddc0SDimitry Andric AddPath("/boot/system/develop/headers/os/media", System, false); 309*04eeddc0SDimitry Andric AddPath("/boot/system/develop/headers/os/midi", System, false); 310*04eeddc0SDimitry Andric AddPath("/boot/system/develop/headers/os/midi2", System, false); 311*04eeddc0SDimitry Andric AddPath("/boot/system/develop/headers/os/net", System, false); 312*04eeddc0SDimitry Andric AddPath("/boot/system/develop/headers/os/opengl", System, false); 313*04eeddc0SDimitry Andric AddPath("/boot/system/develop/headers/os/storage", System, false); 314*04eeddc0SDimitry Andric AddPath("/boot/system/develop/headers/os/support", System, false); 315*04eeddc0SDimitry Andric AddPath("/boot/system/develop/headers/os/translation", System, false); 316*04eeddc0SDimitry Andric AddPath("/boot/system/develop/headers/os/add-ons/graphics", System, false); 317*04eeddc0SDimitry Andric AddPath("/boot/system/develop/headers/os/add-ons/input_server", System, false); 318*04eeddc0SDimitry Andric AddPath("/boot/system/develop/headers/os/add-ons/mail_daemon", System, false); 319*04eeddc0SDimitry Andric AddPath("/boot/system/develop/headers/os/add-ons/registrar", System, false); 320*04eeddc0SDimitry Andric AddPath("/boot/system/develop/headers/os/add-ons/screen_saver", System, false); 321*04eeddc0SDimitry Andric AddPath("/boot/system/develop/headers/os/add-ons/tracker", System, false); 322*04eeddc0SDimitry Andric AddPath("/boot/system/develop/headers/os/be_apps/Deskbar", System, false); 323*04eeddc0SDimitry Andric AddPath("/boot/system/develop/headers/os/be_apps/NetPositive", System, false); 324*04eeddc0SDimitry Andric AddPath("/boot/system/develop/headers/os/be_apps/Tracker", System, false); 325*04eeddc0SDimitry Andric AddPath("/boot/system/develop/headers/3rdparty", System, false); 326*04eeddc0SDimitry Andric AddPath("/boot/system/develop/headers/bsd", System, false); 327*04eeddc0SDimitry Andric AddPath("/boot/system/develop/headers/glibc", System, false); 328*04eeddc0SDimitry Andric AddPath("/boot/system/develop/headers/posix", System, false); 329*04eeddc0SDimitry Andric AddPath("/boot/system/develop/headers", System, false); 330*04eeddc0SDimitry Andric break; 331*04eeddc0SDimitry Andric case llvm::Triple::RTEMS: 332*04eeddc0SDimitry Andric break; 333*04eeddc0SDimitry Andric case llvm::Triple::Win32: 334*04eeddc0SDimitry Andric switch (triple.getEnvironment()) { 335*04eeddc0SDimitry Andric default: llvm_unreachable("Include management is handled in the driver."); 336*04eeddc0SDimitry Andric case llvm::Triple::Cygnus: 337*04eeddc0SDimitry Andric AddPath("/usr/include/w32api", System, false); 338*04eeddc0SDimitry Andric break; 339*04eeddc0SDimitry Andric case llvm::Triple::GNU: 340*04eeddc0SDimitry Andric break; 341*04eeddc0SDimitry Andric } 342*04eeddc0SDimitry Andric break; 343*04eeddc0SDimitry Andric default: 344*04eeddc0SDimitry Andric break; 345*04eeddc0SDimitry Andric } 346*04eeddc0SDimitry Andric 347*04eeddc0SDimitry Andric switch (os) { 348*04eeddc0SDimitry Andric case llvm::Triple::CloudABI: 349*04eeddc0SDimitry Andric case llvm::Triple::RTEMS: 350*04eeddc0SDimitry Andric case llvm::Triple::NaCl: 351*04eeddc0SDimitry Andric case llvm::Triple::ELFIAMCU: 352*04eeddc0SDimitry Andric case llvm::Triple::Fuchsia: 353*04eeddc0SDimitry Andric break; 354*04eeddc0SDimitry Andric case llvm::Triple::PS4: { 355*04eeddc0SDimitry Andric // <isysroot> gets prepended later in AddPath(). 356*04eeddc0SDimitry Andric std::string BaseSDKPath; 357*04eeddc0SDimitry Andric if (!HasSysroot) { 358*04eeddc0SDimitry Andric const char *envValue = getenv("SCE_ORBIS_SDK_DIR"); 359*04eeddc0SDimitry Andric if (envValue) 360*04eeddc0SDimitry Andric BaseSDKPath = envValue; 361*04eeddc0SDimitry Andric else { 362*04eeddc0SDimitry Andric // HSOpts.ResourceDir variable contains the location of Clang's 363*04eeddc0SDimitry Andric // resource files. 364*04eeddc0SDimitry Andric // Assuming that Clang is configured for PS4 without 365*04eeddc0SDimitry Andric // --with-clang-resource-dir option, the location of Clang's resource 366*04eeddc0SDimitry Andric // files is <SDK_DIR>/host_tools/lib/clang 367*04eeddc0SDimitry Andric SmallString<128> P = StringRef(HSOpts.ResourceDir); 368*04eeddc0SDimitry Andric llvm::sys::path::append(P, "../../.."); 369*04eeddc0SDimitry Andric BaseSDKPath = std::string(P.str()); 370*04eeddc0SDimitry Andric } 371*04eeddc0SDimitry Andric } 372*04eeddc0SDimitry Andric AddPath(BaseSDKPath + "/target/include", System, false); 373*04eeddc0SDimitry Andric if (triple.isPS4CPU()) 374*04eeddc0SDimitry Andric AddPath(BaseSDKPath + "/target/include_common", System, false); 375*04eeddc0SDimitry Andric LLVM_FALLTHROUGH; 376*04eeddc0SDimitry Andric } 377*04eeddc0SDimitry Andric default: 378*04eeddc0SDimitry Andric AddPath("/usr/include", ExternCSystem, false); 379*04eeddc0SDimitry Andric break; 380*04eeddc0SDimitry Andric } 381*04eeddc0SDimitry Andric } 382*04eeddc0SDimitry Andric 383*04eeddc0SDimitry Andric void InitHeaderSearch::AddDefaultCPlusPlusIncludePaths( 384*04eeddc0SDimitry Andric const LangOptions &LangOpts, const llvm::Triple &triple, 385*04eeddc0SDimitry Andric const HeaderSearchOptions &HSOpts) { 386*04eeddc0SDimitry Andric llvm::Triple::OSType os = triple.getOS(); 387*04eeddc0SDimitry Andric // FIXME: temporary hack: hard-coded paths. 388*04eeddc0SDimitry Andric 389*04eeddc0SDimitry Andric if (triple.isOSDarwin()) { 390*04eeddc0SDimitry Andric llvm_unreachable("Include management is handled in the driver."); 391*04eeddc0SDimitry Andric } 392*04eeddc0SDimitry Andric 393*04eeddc0SDimitry Andric switch (os) { 394*04eeddc0SDimitry Andric case llvm::Triple::Linux: 395*04eeddc0SDimitry Andric case llvm::Triple::Hurd: 396*04eeddc0SDimitry Andric case llvm::Triple::Solaris: 397*04eeddc0SDimitry Andric case llvm::Triple::AIX: 398*04eeddc0SDimitry Andric llvm_unreachable("Include management is handled in the driver."); 399*04eeddc0SDimitry Andric break; 400*04eeddc0SDimitry Andric case llvm::Triple::Win32: 401*04eeddc0SDimitry Andric switch (triple.getEnvironment()) { 402*04eeddc0SDimitry Andric default: llvm_unreachable("Include management is handled in the driver."); 403*04eeddc0SDimitry Andric case llvm::Triple::Cygnus: 404*04eeddc0SDimitry Andric // Cygwin-1.7 405*04eeddc0SDimitry Andric AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.7.3"); 406*04eeddc0SDimitry Andric AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.5.3"); 407*04eeddc0SDimitry Andric AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.3.4"); 408*04eeddc0SDimitry Andric // g++-4 / Cygwin-1.5 409*04eeddc0SDimitry Andric AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.3.2"); 410*04eeddc0SDimitry Andric break; 411*04eeddc0SDimitry Andric } 412*04eeddc0SDimitry Andric break; 413*04eeddc0SDimitry Andric case llvm::Triple::DragonFly: 414*04eeddc0SDimitry Andric AddPath("/usr/include/c++/5.0", CXXSystem, false); 415*04eeddc0SDimitry Andric break; 416*04eeddc0SDimitry Andric case llvm::Triple::Minix: 417*04eeddc0SDimitry Andric AddGnuCPlusPlusIncludePaths("/usr/gnu/include/c++/4.4.3", 418*04eeddc0SDimitry Andric "", "", "", triple); 419*04eeddc0SDimitry Andric break; 420*04eeddc0SDimitry Andric default: 421*04eeddc0SDimitry Andric break; 422*04eeddc0SDimitry Andric } 423*04eeddc0SDimitry Andric } 424*04eeddc0SDimitry Andric 425*04eeddc0SDimitry Andric void InitHeaderSearch::AddDefaultIncludePaths(const LangOptions &Lang, 426*04eeddc0SDimitry Andric const llvm::Triple &triple, 427*04eeddc0SDimitry Andric const HeaderSearchOptions &HSOpts) { 428*04eeddc0SDimitry Andric // NB: This code path is going away. All of the logic is moving into the 429*04eeddc0SDimitry Andric // driver which has the information necessary to do target-specific 430*04eeddc0SDimitry Andric // selections of default include paths. Each target which moves there will be 431*04eeddc0SDimitry Andric // exempted from this logic here until we can delete the entire pile of code. 432*04eeddc0SDimitry Andric switch (triple.getOS()) { 433*04eeddc0SDimitry Andric default: 434*04eeddc0SDimitry Andric break; // Everything else continues to use this routine's logic. 435*04eeddc0SDimitry Andric 436*04eeddc0SDimitry Andric case llvm::Triple::Emscripten: 437*04eeddc0SDimitry Andric case llvm::Triple::Linux: 438*04eeddc0SDimitry Andric case llvm::Triple::Hurd: 439*04eeddc0SDimitry Andric case llvm::Triple::OpenBSD: 440*04eeddc0SDimitry Andric case llvm::Triple::Solaris: 441*04eeddc0SDimitry Andric case llvm::Triple::WASI: 442*04eeddc0SDimitry Andric case llvm::Triple::AIX: 443*04eeddc0SDimitry Andric return; 444*04eeddc0SDimitry Andric 445*04eeddc0SDimitry Andric case llvm::Triple::Win32: 446*04eeddc0SDimitry Andric if (triple.getEnvironment() != llvm::Triple::Cygnus || 447*04eeddc0SDimitry Andric triple.isOSBinFormatMachO()) 448*04eeddc0SDimitry Andric return; 449*04eeddc0SDimitry Andric break; 450*04eeddc0SDimitry Andric 451*04eeddc0SDimitry Andric case llvm::Triple::UnknownOS: 452*04eeddc0SDimitry Andric if (triple.isWasm()) 453*04eeddc0SDimitry Andric return; 454*04eeddc0SDimitry Andric break; 455*04eeddc0SDimitry Andric } 456*04eeddc0SDimitry Andric 457*04eeddc0SDimitry Andric // All header search logic is handled in the Driver for Darwin. 458*04eeddc0SDimitry Andric if (triple.isOSDarwin()) { 459*04eeddc0SDimitry Andric if (HSOpts.UseStandardSystemIncludes) { 460*04eeddc0SDimitry Andric // Add the default framework include paths on Darwin. 461*04eeddc0SDimitry Andric AddPath("/System/Library/Frameworks", System, true); 462*04eeddc0SDimitry Andric AddPath("/Library/Frameworks", System, true); 463*04eeddc0SDimitry Andric } 464*04eeddc0SDimitry Andric return; 465*04eeddc0SDimitry Andric } 466*04eeddc0SDimitry Andric 467*04eeddc0SDimitry Andric if (Lang.CPlusPlus && !Lang.AsmPreprocessor && 468*04eeddc0SDimitry Andric HSOpts.UseStandardCXXIncludes && HSOpts.UseStandardSystemIncludes) { 469*04eeddc0SDimitry Andric if (HSOpts.UseLibcxx) { 470*04eeddc0SDimitry Andric AddPath("/usr/include/c++/v1", CXXSystem, false); 471*04eeddc0SDimitry Andric } else { 472*04eeddc0SDimitry Andric AddDefaultCPlusPlusIncludePaths(Lang, triple, HSOpts); 473*04eeddc0SDimitry Andric } 474*04eeddc0SDimitry Andric } 475*04eeddc0SDimitry Andric 476*04eeddc0SDimitry Andric AddDefaultCIncludePaths(triple, HSOpts); 477*04eeddc0SDimitry Andric } 478*04eeddc0SDimitry Andric 479*04eeddc0SDimitry Andric /// RemoveDuplicates - If there are duplicate directory entries in the specified 480*04eeddc0SDimitry Andric /// search list, remove the later (dead) ones. Returns the number of non-system 481*04eeddc0SDimitry Andric /// headers removed, which is used to update NumAngled. 482*04eeddc0SDimitry Andric static unsigned RemoveDuplicates(std::vector<DirectoryLookupInfo> &SearchList, 483*04eeddc0SDimitry Andric unsigned First, bool Verbose) { 484*04eeddc0SDimitry Andric llvm::SmallPtrSet<const DirectoryEntry *, 8> SeenDirs; 485*04eeddc0SDimitry Andric llvm::SmallPtrSet<const DirectoryEntry *, 8> SeenFrameworkDirs; 486*04eeddc0SDimitry Andric llvm::SmallPtrSet<const HeaderMap *, 8> SeenHeaderMaps; 487*04eeddc0SDimitry Andric unsigned NonSystemRemoved = 0; 488*04eeddc0SDimitry Andric for (unsigned i = First; i != SearchList.size(); ++i) { 489*04eeddc0SDimitry Andric unsigned DirToRemove = i; 490*04eeddc0SDimitry Andric 491*04eeddc0SDimitry Andric const DirectoryLookup &CurEntry = SearchList[i].Lookup; 492*04eeddc0SDimitry Andric 493*04eeddc0SDimitry Andric if (CurEntry.isNormalDir()) { 494*04eeddc0SDimitry Andric // If this isn't the first time we've seen this dir, remove it. 495*04eeddc0SDimitry Andric if (SeenDirs.insert(CurEntry.getDir()).second) 496*04eeddc0SDimitry Andric continue; 497*04eeddc0SDimitry Andric } else if (CurEntry.isFramework()) { 498*04eeddc0SDimitry Andric // If this isn't the first time we've seen this framework dir, remove it. 499*04eeddc0SDimitry Andric if (SeenFrameworkDirs.insert(CurEntry.getFrameworkDir()).second) 500*04eeddc0SDimitry Andric continue; 501*04eeddc0SDimitry Andric } else { 502*04eeddc0SDimitry Andric assert(CurEntry.isHeaderMap() && "Not a headermap or normal dir?"); 503*04eeddc0SDimitry Andric // If this isn't the first time we've seen this headermap, remove it. 504*04eeddc0SDimitry Andric if (SeenHeaderMaps.insert(CurEntry.getHeaderMap()).second) 505*04eeddc0SDimitry Andric continue; 506*04eeddc0SDimitry Andric } 507*04eeddc0SDimitry Andric 508*04eeddc0SDimitry Andric // If we have a normal #include dir/framework/headermap that is shadowed 509*04eeddc0SDimitry Andric // later in the chain by a system include location, we actually want to 510*04eeddc0SDimitry Andric // ignore the user's request and drop the user dir... keeping the system 511*04eeddc0SDimitry Andric // dir. This is weird, but required to emulate GCC's search path correctly. 512*04eeddc0SDimitry Andric // 513*04eeddc0SDimitry Andric // Since dupes of system dirs are rare, just rescan to find the original 514*04eeddc0SDimitry Andric // that we're nuking instead of using a DenseMap. 515*04eeddc0SDimitry Andric if (CurEntry.getDirCharacteristic() != SrcMgr::C_User) { 516*04eeddc0SDimitry Andric // Find the dir that this is the same of. 517*04eeddc0SDimitry Andric unsigned FirstDir; 518*04eeddc0SDimitry Andric for (FirstDir = First;; ++FirstDir) { 519*04eeddc0SDimitry Andric assert(FirstDir != i && "Didn't find dupe?"); 520*04eeddc0SDimitry Andric 521*04eeddc0SDimitry Andric const DirectoryLookup &SearchEntry = SearchList[FirstDir].Lookup; 522*04eeddc0SDimitry Andric 523*04eeddc0SDimitry Andric // If these are different lookup types, then they can't be the dupe. 524*04eeddc0SDimitry Andric if (SearchEntry.getLookupType() != CurEntry.getLookupType()) 525*04eeddc0SDimitry Andric continue; 526*04eeddc0SDimitry Andric 527*04eeddc0SDimitry Andric bool isSame; 528*04eeddc0SDimitry Andric if (CurEntry.isNormalDir()) 529*04eeddc0SDimitry Andric isSame = SearchEntry.getDir() == CurEntry.getDir(); 530*04eeddc0SDimitry Andric else if (CurEntry.isFramework()) 531*04eeddc0SDimitry Andric isSame = SearchEntry.getFrameworkDir() == CurEntry.getFrameworkDir(); 532*04eeddc0SDimitry Andric else { 533*04eeddc0SDimitry Andric assert(CurEntry.isHeaderMap() && "Not a headermap or normal dir?"); 534*04eeddc0SDimitry Andric isSame = SearchEntry.getHeaderMap() == CurEntry.getHeaderMap(); 535*04eeddc0SDimitry Andric } 536*04eeddc0SDimitry Andric 537*04eeddc0SDimitry Andric if (isSame) 538*04eeddc0SDimitry Andric break; 539*04eeddc0SDimitry Andric } 540*04eeddc0SDimitry Andric 541*04eeddc0SDimitry Andric // If the first dir in the search path is a non-system dir, zap it 542*04eeddc0SDimitry Andric // instead of the system one. 543*04eeddc0SDimitry Andric if (SearchList[FirstDir].Lookup.getDirCharacteristic() == SrcMgr::C_User) 544*04eeddc0SDimitry Andric DirToRemove = FirstDir; 545*04eeddc0SDimitry Andric } 546*04eeddc0SDimitry Andric 547*04eeddc0SDimitry Andric if (Verbose) { 548*04eeddc0SDimitry Andric llvm::errs() << "ignoring duplicate directory \"" 549*04eeddc0SDimitry Andric << CurEntry.getName() << "\"\n"; 550*04eeddc0SDimitry Andric if (DirToRemove != i) 551*04eeddc0SDimitry Andric llvm::errs() << " as it is a non-system directory that duplicates " 552*04eeddc0SDimitry Andric << "a system directory\n"; 553*04eeddc0SDimitry Andric } 554*04eeddc0SDimitry Andric if (DirToRemove != i) 555*04eeddc0SDimitry Andric ++NonSystemRemoved; 556*04eeddc0SDimitry Andric 557*04eeddc0SDimitry Andric // This is reached if the current entry is a duplicate. Remove the 558*04eeddc0SDimitry Andric // DirToRemove (usually the current dir). 559*04eeddc0SDimitry Andric SearchList.erase(SearchList.begin()+DirToRemove); 560*04eeddc0SDimitry Andric --i; 561*04eeddc0SDimitry Andric } 562*04eeddc0SDimitry Andric return NonSystemRemoved; 563*04eeddc0SDimitry Andric } 564*04eeddc0SDimitry Andric 565*04eeddc0SDimitry Andric /// Extract DirectoryLookups from DirectoryLookupInfos. 566*04eeddc0SDimitry Andric static std::vector<DirectoryLookup> 567*04eeddc0SDimitry Andric extractLookups(const std::vector<DirectoryLookupInfo> &Infos) { 568*04eeddc0SDimitry Andric std::vector<DirectoryLookup> Lookups; 569*04eeddc0SDimitry Andric Lookups.reserve(Infos.size()); 570*04eeddc0SDimitry Andric llvm::transform(Infos, std::back_inserter(Lookups), 571*04eeddc0SDimitry Andric [](const DirectoryLookupInfo &Info) { return Info.Lookup; }); 572*04eeddc0SDimitry Andric return Lookups; 573*04eeddc0SDimitry Andric } 574*04eeddc0SDimitry Andric 575*04eeddc0SDimitry Andric /// Collect the mapping between indices of DirectoryLookups and UserEntries. 576*04eeddc0SDimitry Andric static llvm::DenseMap<unsigned, unsigned> 577*04eeddc0SDimitry Andric mapToUserEntries(const std::vector<DirectoryLookupInfo> &Infos) { 578*04eeddc0SDimitry Andric llvm::DenseMap<unsigned, unsigned> LookupsToUserEntries; 579*04eeddc0SDimitry Andric for (unsigned I = 0, E = Infos.size(); I < E; ++I) { 580*04eeddc0SDimitry Andric // Check whether this DirectoryLookup maps to a HeaderSearch::UserEntry. 581*04eeddc0SDimitry Andric if (Infos[I].UserEntryIdx) 582*04eeddc0SDimitry Andric LookupsToUserEntries.insert({I, *Infos[I].UserEntryIdx}); 583*04eeddc0SDimitry Andric } 584*04eeddc0SDimitry Andric return LookupsToUserEntries; 585*04eeddc0SDimitry Andric } 586*04eeddc0SDimitry Andric 587*04eeddc0SDimitry Andric void InitHeaderSearch::Realize(const LangOptions &Lang) { 588*04eeddc0SDimitry Andric // Concatenate ANGLE+SYSTEM+AFTER chains together into SearchList. 589*04eeddc0SDimitry Andric std::vector<DirectoryLookupInfo> SearchList; 590*04eeddc0SDimitry Andric SearchList.reserve(IncludePath.size()); 591*04eeddc0SDimitry Andric 592*04eeddc0SDimitry Andric // Quoted arguments go first. 593*04eeddc0SDimitry Andric for (auto &Include : IncludePath) 594*04eeddc0SDimitry Andric if (Include.Group == Quoted) 595*04eeddc0SDimitry Andric SearchList.push_back(Include); 596*04eeddc0SDimitry Andric 597*04eeddc0SDimitry Andric // Deduplicate and remember index. 598*04eeddc0SDimitry Andric RemoveDuplicates(SearchList, 0, Verbose); 599*04eeddc0SDimitry Andric unsigned NumQuoted = SearchList.size(); 600*04eeddc0SDimitry Andric 601*04eeddc0SDimitry Andric for (auto &Include : IncludePath) 602*04eeddc0SDimitry Andric if (Include.Group == Angled || Include.Group == IndexHeaderMap) 603*04eeddc0SDimitry Andric SearchList.push_back(Include); 604*04eeddc0SDimitry Andric 605*04eeddc0SDimitry Andric RemoveDuplicates(SearchList, NumQuoted, Verbose); 606*04eeddc0SDimitry Andric unsigned NumAngled = SearchList.size(); 607*04eeddc0SDimitry Andric 608*04eeddc0SDimitry Andric for (auto &Include : IncludePath) 609*04eeddc0SDimitry Andric if (Include.Group == System || Include.Group == ExternCSystem || 610*04eeddc0SDimitry Andric (!Lang.ObjC && !Lang.CPlusPlus && Include.Group == CSystem) || 611*04eeddc0SDimitry Andric (/*FIXME !Lang.ObjC && */ Lang.CPlusPlus && 612*04eeddc0SDimitry Andric Include.Group == CXXSystem) || 613*04eeddc0SDimitry Andric (Lang.ObjC && !Lang.CPlusPlus && Include.Group == ObjCSystem) || 614*04eeddc0SDimitry Andric (Lang.ObjC && Lang.CPlusPlus && Include.Group == ObjCXXSystem)) 615*04eeddc0SDimitry Andric SearchList.push_back(Include); 616*04eeddc0SDimitry Andric 617*04eeddc0SDimitry Andric for (auto &Include : IncludePath) 618*04eeddc0SDimitry Andric if (Include.Group == After) 619*04eeddc0SDimitry Andric SearchList.push_back(Include); 620*04eeddc0SDimitry Andric 621*04eeddc0SDimitry Andric // Remove duplicates across both the Angled and System directories. GCC does 622*04eeddc0SDimitry Andric // this and failing to remove duplicates across these two groups breaks 623*04eeddc0SDimitry Andric // #include_next. 624*04eeddc0SDimitry Andric unsigned NonSystemRemoved = RemoveDuplicates(SearchList, NumQuoted, Verbose); 625*04eeddc0SDimitry Andric NumAngled -= NonSystemRemoved; 626*04eeddc0SDimitry Andric 627*04eeddc0SDimitry Andric bool DontSearchCurDir = false; // TODO: set to true if -I- is set? 628*04eeddc0SDimitry Andric Headers.SetSearchPaths(extractLookups(SearchList), NumQuoted, NumAngled, 629*04eeddc0SDimitry Andric DontSearchCurDir, mapToUserEntries(SearchList)); 630*04eeddc0SDimitry Andric 631*04eeddc0SDimitry Andric Headers.SetSystemHeaderPrefixes(SystemHeaderPrefixes); 632*04eeddc0SDimitry Andric 633*04eeddc0SDimitry Andric // If verbose, print the list of directories that will be searched. 634*04eeddc0SDimitry Andric if (Verbose) { 635*04eeddc0SDimitry Andric llvm::errs() << "#include \"...\" search starts here:\n"; 636*04eeddc0SDimitry Andric for (unsigned i = 0, e = SearchList.size(); i != e; ++i) { 637*04eeddc0SDimitry Andric if (i == NumQuoted) 638*04eeddc0SDimitry Andric llvm::errs() << "#include <...> search starts here:\n"; 639*04eeddc0SDimitry Andric StringRef Name = SearchList[i].Lookup.getName(); 640*04eeddc0SDimitry Andric const char *Suffix; 641*04eeddc0SDimitry Andric if (SearchList[i].Lookup.isNormalDir()) 642*04eeddc0SDimitry Andric Suffix = ""; 643*04eeddc0SDimitry Andric else if (SearchList[i].Lookup.isFramework()) 644*04eeddc0SDimitry Andric Suffix = " (framework directory)"; 645*04eeddc0SDimitry Andric else { 646*04eeddc0SDimitry Andric assert(SearchList[i].Lookup.isHeaderMap() && "Unknown DirectoryLookup"); 647*04eeddc0SDimitry Andric Suffix = " (headermap)"; 648*04eeddc0SDimitry Andric } 649*04eeddc0SDimitry Andric llvm::errs() << " " << Name << Suffix << "\n"; 650*04eeddc0SDimitry Andric } 651*04eeddc0SDimitry Andric llvm::errs() << "End of search list.\n"; 652*04eeddc0SDimitry Andric } 653*04eeddc0SDimitry Andric } 654*04eeddc0SDimitry Andric 655*04eeddc0SDimitry Andric void clang::ApplyHeaderSearchOptions(HeaderSearch &HS, 656*04eeddc0SDimitry Andric const HeaderSearchOptions &HSOpts, 657*04eeddc0SDimitry Andric const LangOptions &Lang, 658*04eeddc0SDimitry Andric const llvm::Triple &Triple) { 659*04eeddc0SDimitry Andric InitHeaderSearch Init(HS, HSOpts.Verbose, HSOpts.Sysroot); 660*04eeddc0SDimitry Andric 661*04eeddc0SDimitry Andric // Add the user defined entries. 662*04eeddc0SDimitry Andric for (unsigned i = 0, e = HSOpts.UserEntries.size(); i != e; ++i) { 663*04eeddc0SDimitry Andric const HeaderSearchOptions::Entry &E = HSOpts.UserEntries[i]; 664*04eeddc0SDimitry Andric if (E.IgnoreSysRoot) { 665*04eeddc0SDimitry Andric Init.AddUnmappedPath(E.Path, E.Group, E.IsFramework, i); 666*04eeddc0SDimitry Andric } else { 667*04eeddc0SDimitry Andric Init.AddPath(E.Path, E.Group, E.IsFramework, i); 668*04eeddc0SDimitry Andric } 669*04eeddc0SDimitry Andric } 670*04eeddc0SDimitry Andric 671*04eeddc0SDimitry Andric Init.AddDefaultIncludePaths(Lang, Triple, HSOpts); 672*04eeddc0SDimitry Andric 673*04eeddc0SDimitry Andric for (unsigned i = 0, e = HSOpts.SystemHeaderPrefixes.size(); i != e; ++i) 674*04eeddc0SDimitry Andric Init.AddSystemHeaderPrefix(HSOpts.SystemHeaderPrefixes[i].Prefix, 675*04eeddc0SDimitry Andric HSOpts.SystemHeaderPrefixes[i].IsSystemHeader); 676*04eeddc0SDimitry Andric 677*04eeddc0SDimitry Andric if (HSOpts.UseBuiltinIncludes) { 678*04eeddc0SDimitry Andric // Set up the builtin include directory in the module map. 679*04eeddc0SDimitry Andric SmallString<128> P = StringRef(HSOpts.ResourceDir); 680*04eeddc0SDimitry Andric llvm::sys::path::append(P, "include"); 681*04eeddc0SDimitry Andric if (auto Dir = HS.getFileMgr().getDirectory(P)) 682*04eeddc0SDimitry Andric HS.getModuleMap().setBuiltinIncludeDir(*Dir); 683*04eeddc0SDimitry Andric } 684*04eeddc0SDimitry Andric 685*04eeddc0SDimitry Andric Init.Realize(Lang); 686*04eeddc0SDimitry Andric } 687