Changeset View
Changeset View
Standalone View
Standalone View
clang/lib/Lex/InitHeaderSearch.cpp
Show All 36 Lines | struct DirectoryLookupInfo { | ||||
DirectoryLookup Lookup; | DirectoryLookup Lookup; | ||||
Optional<unsigned> UserEntryIdx; | Optional<unsigned> UserEntryIdx; | ||||
DirectoryLookupInfo(IncludeDirGroup Group, DirectoryLookup Lookup, | DirectoryLookupInfo(IncludeDirGroup Group, DirectoryLookup Lookup, | ||||
Optional<unsigned> UserEntryIdx) | Optional<unsigned> UserEntryIdx) | ||||
: Group(Group), Lookup(Lookup), UserEntryIdx(UserEntryIdx) {} | : Group(Group), Lookup(Lookup), UserEntryIdx(UserEntryIdx) {} | ||||
}; | }; | ||||
/// InitHeaderSearch - This class makes it easier to set the search paths of | /// This class makes it easier to set the search paths of a HeaderSearch object. | ||||
/// a HeaderSearch object. InitHeaderSearch stores several search path lists | /// InitHeaderSearch stores several search path lists internally, which can be | ||||
/// internally, which can be sent to a HeaderSearch object in one swoop. | /// sent to a HeaderSearch object in one swoop. | ||||
class InitHeaderSearch { | class InitHeaderSearch { | ||||
std::vector<DirectoryLookupInfo> IncludePath; | std::vector<DirectoryLookupInfo> IncludePath; | ||||
std::vector<std::pair<std::string, bool> > SystemHeaderPrefixes; | std::vector<std::pair<std::string, bool> > SystemHeaderPrefixes; | ||||
HeaderSearch &Headers; | HeaderSearch &Headers; | ||||
bool Verbose; | bool Verbose; | ||||
std::string IncludeSysroot; | std::string IncludeSysroot; | ||||
bool HasSysroot; | bool HasSysroot; | ||||
public: | public: | ||||
InitHeaderSearch(HeaderSearch &HS, bool verbose, StringRef sysroot) | InitHeaderSearch(HeaderSearch &HS, bool verbose, StringRef sysroot) | ||||
: Headers(HS), Verbose(verbose), IncludeSysroot(std::string(sysroot)), | : Headers(HS), Verbose(verbose), IncludeSysroot(std::string(sysroot)), | ||||
HasSysroot(!(sysroot.empty() || sysroot == "/")) {} | HasSysroot(!(sysroot.empty() || sysroot == "/")) {} | ||||
/// AddPath - Add the specified path to the specified group list, prefixing | /// Add the specified path to the specified group list, prefixing the sysroot | ||||
/// the sysroot if used. | /// if used. | ||||
/// Returns true if the path exists, false if it was ignored. | /// Returns true if the path exists, false if it was ignored. | ||||
bool AddPath(const Twine &Path, IncludeDirGroup Group, bool isFramework, | bool AddPath(const Twine &Path, IncludeDirGroup Group, bool isFramework, | ||||
Optional<unsigned> UserEntryIdx = None); | Optional<unsigned> UserEntryIdx = None); | ||||
/// AddUnmappedPath - Add the specified path to the specified group list, | /// Add the specified path to the specified group list, without performing any | ||||
/// without performing any sysroot remapping. | /// sysroot remapping. | ||||
/// Returns true if the path exists, false if it was ignored. | /// Returns true if the path exists, false if it was ignored. | ||||
bool AddUnmappedPath(const Twine &Path, IncludeDirGroup Group, | bool AddUnmappedPath(const Twine &Path, IncludeDirGroup Group, | ||||
bool isFramework, | bool isFramework, | ||||
Optional<unsigned> UserEntryIdx = None); | Optional<unsigned> UserEntryIdx = None); | ||||
/// AddSystemHeaderPrefix - Add the specified prefix to the system header | /// Add the specified prefix to the system header prefix list. | ||||
/// prefix list. | |||||
void AddSystemHeaderPrefix(StringRef Prefix, bool IsSystemHeader) { | void AddSystemHeaderPrefix(StringRef Prefix, bool IsSystemHeader) { | ||||
SystemHeaderPrefixes.emplace_back(std::string(Prefix), IsSystemHeader); | SystemHeaderPrefixes.emplace_back(std::string(Prefix), IsSystemHeader); | ||||
} | } | ||||
/// AddGnuCPlusPlusIncludePaths - Add the necessary paths to support a gnu | /// Add the necessary paths to support a gnu libstdc++. | ||||
/// libstdc++. | |||||
/// Returns true if the \p Base path was found, false if it does not exist. | /// Returns true if the \p Base path was found, false if it does not exist. | ||||
bool AddGnuCPlusPlusIncludePaths(StringRef Base, StringRef ArchDir, | bool AddGnuCPlusPlusIncludePaths(StringRef Base, StringRef ArchDir, | ||||
StringRef Dir32, StringRef Dir64, | StringRef Dir32, StringRef Dir64, | ||||
const llvm::Triple &triple); | const llvm::Triple &triple); | ||||
/// AddMinGWCPlusPlusIncludePaths - Add the necessary paths to support a MinGW | /// Add the necessary paths to support a MinGW libstdc++. | ||||
/// libstdc++. | |||||
void AddMinGWCPlusPlusIncludePaths(StringRef Base, | void AddMinGWCPlusPlusIncludePaths(StringRef Base, | ||||
StringRef Arch, | StringRef Arch, | ||||
StringRef Version); | StringRef Version); | ||||
// AddDefaultCIncludePaths - Add paths that should always be searched. | /// Add paths that should always be searched. | ||||
void AddDefaultCIncludePaths(const llvm::Triple &triple, | void AddDefaultCIncludePaths(const llvm::Triple &triple, | ||||
const HeaderSearchOptions &HSOpts); | const HeaderSearchOptions &HSOpts); | ||||
// AddDefaultCPlusPlusIncludePaths - Add paths that should be searched when | /// Add paths that should be searched when compiling c++. | ||||
// compiling c++. | |||||
void AddDefaultCPlusPlusIncludePaths(const LangOptions &LangOpts, | void AddDefaultCPlusPlusIncludePaths(const LangOptions &LangOpts, | ||||
const llvm::Triple &triple, | const llvm::Triple &triple, | ||||
const HeaderSearchOptions &HSOpts); | const HeaderSearchOptions &HSOpts); | ||||
/// AddDefaultSystemIncludePaths - Adds the default system include paths so | /// Returns true iff AddDefaultIncludePaths should do anything. If this | ||||
MaskRay: Drop `ShouldAddDefaultIncludePaths - `. It is not recommended for new code.
| |||||
/// that e.g. stdio.h is found. | /// returns false, include paths should instead be handled in the driver. | ||||
multiple spaces => one space MaskRay: multiple spaces => one space | |||||
not done. /// => /// MaskRay: not done. `/// ` => `/// ` | |||||
bool ShouldAddDefaultIncludePaths(const llvm::Triple &triple); | |||||
/// Adds the default system include paths so that e.g. stdio.h is found. | |||||
void AddDefaultIncludePaths(const LangOptions &Lang, | void AddDefaultIncludePaths(const LangOptions &Lang, | ||||
const llvm::Triple &triple, | const llvm::Triple &triple, | ||||
const HeaderSearchOptions &HSOpts); | const HeaderSearchOptions &HSOpts); | ||||
/// Realize - Merges all search path lists into one list and send it to | /// Merges all search path lists into one list and send it to HeaderSearch. | ||||
/// HeaderSearch. | |||||
void Realize(const LangOptions &Lang); | void Realize(const LangOptions &Lang); | ||||
}; | }; | ||||
} // end anonymous namespace. | } // end anonymous namespace. | ||||
static bool CanPrefixSysroot(StringRef Path) { | static bool CanPrefixSysroot(StringRef Path) { | ||||
#if defined(_WIN32) | #if defined(_WIN32) | ||||
return !Path.empty() && llvm::sys::path::is_separator(Path[0]); | return !Path.empty() && llvm::sys::path::is_separator(Path[0]); | ||||
▲ Show 20 Lines • Show All 101 Lines • ▼ Show 20 Lines | void InitHeaderSearch::AddMinGWCPlusPlusIncludePaths(StringRef Base, | ||||
AddPath(Base + "/" + Arch + "/" + Version + "/include/c++/" + Arch, | AddPath(Base + "/" + Arch + "/" + Version + "/include/c++/" + Arch, | ||||
CXXSystem, false); | CXXSystem, false); | ||||
AddPath(Base + "/" + Arch + "/" + Version + "/include/c++/backward", | AddPath(Base + "/" + Arch + "/" + Version + "/include/c++/backward", | ||||
CXXSystem, false); | CXXSystem, false); | ||||
} | } | ||||
void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple, | void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple, | ||||
const HeaderSearchOptions &HSOpts) { | const HeaderSearchOptions &HSOpts) { | ||||
llvm::Triple::OSType os = triple.getOS(); | if (!ShouldAddDefaultIncludePaths(triple)) | ||||
if (triple.isOSDarwin()) { | |||||
llvm_unreachable("Include management is handled in the driver."); | llvm_unreachable("Include management is handled in the driver."); | ||||
drop braces around simple single statements MaskRay: drop braces around simple single statements | |||||
} | |||||
llvm::Triple::OSType os = triple.getOS(); | |||||
if (HSOpts.UseStandardSystemIncludes) { | if (HSOpts.UseStandardSystemIncludes) { | ||||
switch (os) { | switch (os) { | ||||
case llvm::Triple::CloudABI: | case llvm::Triple::CloudABI: | ||||
case llvm::Triple::FreeBSD: | |||||
case llvm::Triple::NetBSD: | case llvm::Triple::NetBSD: | ||||
case llvm::Triple::OpenBSD: | |||||
case llvm::Triple::NaCl: | case llvm::Triple::NaCl: | ||||
case llvm::Triple::PS4: | case llvm::Triple::PS4: | ||||
case llvm::Triple::PS5: | case llvm::Triple::PS5: | ||||
case llvm::Triple::ELFIAMCU: | case llvm::Triple::ELFIAMCU: | ||||
case llvm::Triple::Fuchsia: | case llvm::Triple::Fuchsia: | ||||
break; | break; | ||||
case llvm::Triple::Win32: | case llvm::Triple::Win32: | ||||
if (triple.getEnvironment() != llvm::Triple::Cygnus) | if (triple.getEnvironment() != llvm::Triple::Cygnus) | ||||
Show All 27 Lines | if (CIncludeDirs != "") { | ||||
SmallVector<StringRef, 5> dirs; | SmallVector<StringRef, 5> dirs; | ||||
CIncludeDirs.split(dirs, ":"); | CIncludeDirs.split(dirs, ":"); | ||||
for (StringRef dir : dirs) | for (StringRef dir : dirs) | ||||
AddPath(dir, ExternCSystem, false); | AddPath(dir, ExternCSystem, false); | ||||
return; | return; | ||||
} | } | ||||
switch (os) { | switch (os) { | ||||
case llvm::Triple::Linux: | |||||
case llvm::Triple::Hurd: | |||||
case llvm::Triple::Solaris: | |||||
case llvm::Triple::OpenBSD: | |||||
llvm_unreachable("Include management is handled in the driver."); | |||||
case llvm::Triple::CloudABI: { | case llvm::Triple::CloudABI: { | ||||
// <sysroot>/<triple>/include | // <sysroot>/<triple>/include | ||||
SmallString<128> P = StringRef(HSOpts.ResourceDir); | SmallString<128> P = StringRef(HSOpts.ResourceDir); | ||||
llvm::sys::path::append(P, "../../..", triple.str(), "include"); | llvm::sys::path::append(P, "../../..", triple.str(), "include"); | ||||
AddPath(P, System, false); | AddPath(P, System, false); | ||||
break; | break; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 84 Lines • ▼ Show 20 Lines | default: | ||||
AddPath("/usr/include", ExternCSystem, false); | AddPath("/usr/include", ExternCSystem, false); | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
void InitHeaderSearch::AddDefaultCPlusPlusIncludePaths( | void InitHeaderSearch::AddDefaultCPlusPlusIncludePaths( | ||||
const LangOptions &LangOpts, const llvm::Triple &triple, | const LangOptions &LangOpts, const llvm::Triple &triple, | ||||
const HeaderSearchOptions &HSOpts) { | const HeaderSearchOptions &HSOpts) { | ||||
llvm::Triple::OSType os = triple.getOS(); | if (!ShouldAddDefaultIncludePaths(triple)) | ||||
// FIXME: temporary hack: hard-coded paths. | |||||
if (triple.isOSDarwin()) { | |||||
llvm_unreachable("Include management is handled in the driver."); | llvm_unreachable("Include management is handled in the driver."); | ||||
} | |||||
// FIXME: temporary hack: hard-coded paths. | |||||
llvm::Triple::OSType os = triple.getOS(); | |||||
move the variable immediately before switch os and move the comment before the variable? Avoid unneeded blank lines MaskRay: move the variable immediately before switch `os` and move the comment before the variable? | |||||
switch (os) { | switch (os) { | ||||
case llvm::Triple::Linux: | |||||
case llvm::Triple::Hurd: | |||||
case llvm::Triple::Solaris: | |||||
case llvm::Triple::AIX: | |||||
llvm_unreachable("Include management is handled in the driver."); | |||||
break; | |||||
case llvm::Triple::Win32: | case llvm::Triple::Win32: | ||||
switch (triple.getEnvironment()) { | switch (triple.getEnvironment()) { | ||||
default: llvm_unreachable("Include management is handled in the driver."); | default: llvm_unreachable("Include management is handled in the driver."); | ||||
case llvm::Triple::Cygnus: | case llvm::Triple::Cygnus: | ||||
// Cygwin-1.7 | // Cygwin-1.7 | ||||
AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.7.3"); | AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.7.3"); | ||||
AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.5.3"); | AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.5.3"); | ||||
AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.3.4"); | AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.3.4"); | ||||
Show All 9 Lines | case llvm::Triple::Minix: | ||||
AddGnuCPlusPlusIncludePaths("/usr/gnu/include/c++/4.4.3", | AddGnuCPlusPlusIncludePaths("/usr/gnu/include/c++/4.4.3", | ||||
"", "", "", triple); | "", "", "", triple); | ||||
break; | break; | ||||
default: | default: | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
void InitHeaderSearch::AddDefaultIncludePaths(const LangOptions &Lang, | bool InitHeaderSearch::ShouldAddDefaultIncludePaths( | ||||
const llvm::Triple &triple, | const llvm::Triple &triple) { | ||||
const HeaderSearchOptions &HSOpts) { | |||||
// NB: This code path is going away. All of the logic is moving into the | |||||
// driver which has the information necessary to do target-specific | |||||
// selections of default include paths. Each target which moves there will be | |||||
// exempted from this logic here until we can delete the entire pile of code. | |||||
switch (triple.getOS()) { | switch (triple.getOS()) { | ||||
default: | case llvm::Triple::AIX: | ||||
break; // Everything else continues to use this routine's logic. | |||||
case llvm::Triple::Emscripten: | case llvm::Triple::Emscripten: | ||||
case llvm::Triple::Linux: | case llvm::Triple::FreeBSD: | ||||
case llvm::Triple::Hurd: | case llvm::Triple::Hurd: | ||||
case llvm::Triple::Linux: | |||||
case llvm::Triple::OpenBSD: | case llvm::Triple::OpenBSD: | ||||
case llvm::Triple::Solaris: | case llvm::Triple::Solaris: | ||||
case llvm::Triple::WASI: | case llvm::Triple::WASI: | ||||
case llvm::Triple::AIX: | return false; | ||||
return; | |||||
case llvm::Triple::Win32: | case llvm::Triple::Win32: | ||||
if (triple.getEnvironment() != llvm::Triple::Cygnus || | if (triple.getEnvironment() != llvm::Triple::Cygnus || | ||||
triple.isOSBinFormatMachO()) | triple.isOSBinFormatMachO()) | ||||
return; | return false; | ||||
break; | break; | ||||
case llvm::Triple::UnknownOS: | case llvm::Triple::UnknownOS: | ||||
if (triple.isWasm()) | if (triple.isWasm()) | ||||
return; | return false; | ||||
break; | |||||
default: | |||||
break; | break; | ||||
} | } | ||||
// All header search logic is handled in the Driver for Darwin. | return true; // Everything else uses AddDefaultIncludePaths(). | ||||
} | |||||
void InitHeaderSearch::AddDefaultIncludePaths( | |||||
const LangOptions &Lang, const llvm::Triple &triple, | |||||
const HeaderSearchOptions &HSOpts) { | |||||
// NB: This code path is going away. All of the logic is moving into the | |||||
// driver which has the information necessary to do target-specific | |||||
// selections of default include paths. Each target which moves there will be | |||||
// exempted from this logic in ShouldAddDefaultIncludePaths() until we can | |||||
// delete the entire pile of code. | |||||
if (!ShouldAddDefaultIncludePaths(triple)) | |||||
return; | |||||
// NOTE: some additional header search logic is handled in the driver for | |||||
// Darwin. | |||||
if (triple.isOSDarwin()) { | if (triple.isOSDarwin()) { | ||||
if (HSOpts.UseStandardSystemIncludes) { | if (HSOpts.UseStandardSystemIncludes) { | ||||
// Add the default framework include paths on Darwin. | // Add the default framework include paths on Darwin. | ||||
if (triple.isDriverKit()) { | if (triple.isDriverKit()) { | ||||
AddPath("/System/DriverKit/System/Library/Frameworks", System, true); | AddPath("/System/DriverKit/System/Library/Frameworks", System, true); | ||||
} | } else { | ||||
else { | |||||
AddPath("/System/Library/Frameworks", System, true); | AddPath("/System/Library/Frameworks", System, true); | ||||
AddPath("/Library/Frameworks", System, true); | AddPath("/Library/Frameworks", System, true); | ||||
} | } | ||||
} | } | ||||
return; | return; | ||||
} | } | ||||
if (Lang.CPlusPlus && !Lang.AsmPreprocessor && | if (Lang.CPlusPlus && !Lang.AsmPreprocessor && | ||||
HSOpts.UseStandardCXXIncludes && HSOpts.UseStandardSystemIncludes) { | HSOpts.UseStandardCXXIncludes && HSOpts.UseStandardSystemIncludes) { | ||||
if (HSOpts.UseLibcxx) { | if (HSOpts.UseLibcxx) { | ||||
AddPath("/usr/include/c++/v1", CXXSystem, false); | AddPath("/usr/include/c++/v1", CXXSystem, false); | ||||
} else { | } else { | ||||
AddDefaultCPlusPlusIncludePaths(Lang, triple, HSOpts); | AddDefaultCPlusPlusIncludePaths(Lang, triple, HSOpts); | ||||
} | } | ||||
} | } | ||||
AddDefaultCIncludePaths(triple, HSOpts); | AddDefaultCIncludePaths(triple, HSOpts); | ||||
} | } | ||||
/// RemoveDuplicates - If there are duplicate directory entries in the specified | /// If there are duplicate directory entries in the specified search list, | ||||
/// search list, remove the later (dead) ones. Returns the number of non-system | /// remove the later (dead) ones. Returns the number of non-system headers | ||||
/// headers removed, which is used to update NumAngled. | /// removed, which is used to update NumAngled. | ||||
static unsigned RemoveDuplicates(std::vector<DirectoryLookupInfo> &SearchList, | static unsigned RemoveDuplicates(std::vector<DirectoryLookupInfo> &SearchList, | ||||
unsigned First, bool Verbose) { | unsigned First, bool Verbose) { | ||||
llvm::SmallPtrSet<const DirectoryEntry *, 8> SeenDirs; | llvm::SmallPtrSet<const DirectoryEntry *, 8> SeenDirs; | ||||
llvm::SmallPtrSet<const DirectoryEntry *, 8> SeenFrameworkDirs; | llvm::SmallPtrSet<const DirectoryEntry *, 8> SeenFrameworkDirs; | ||||
llvm::SmallPtrSet<const HeaderMap *, 8> SeenHeaderMaps; | llvm::SmallPtrSet<const HeaderMap *, 8> SeenHeaderMaps; | ||||
unsigned NonSystemRemoved = 0; | unsigned NonSystemRemoved = 0; | ||||
for (unsigned i = First; i != SearchList.size(); ++i) { | for (unsigned i = First; i != SearchList.size(); ++i) { | ||||
unsigned DirToRemove = i; | unsigned DirToRemove = i; | ||||
▲ Show 20 Lines • Show All 197 Lines • Show Last 20 Lines |
Drop ShouldAddDefaultIncludePaths - . It is not recommended for new code.