15 #include "clang/Config/config.h" 21 #include "llvm/ADT/SmallPtrSet.h" 22 #include "llvm/ADT/SmallString.h" 23 #include "llvm/ADT/SmallVector.h" 24 #include "llvm/ADT/StringExtras.h" 25 #include "llvm/ADT/Triple.h" 26 #include "llvm/ADT/Twine.h" 27 #include "llvm/Support/ErrorHandling.h" 28 #include "llvm/Support/Path.h" 29 #include "llvm/Support/raw_ostream.h" 31 using namespace clang;
39 class InitHeaderSearch {
40 std::vector<std::pair<IncludeDirGroup, DirectoryLookup> > IncludePath;
43 std::vector<std::pair<std::string, bool> > SystemHeaderPrefixes;
46 std::string IncludeSysroot;
51 InitHeaderSearch(
HeaderSearch &HS,
bool verbose, StringRef sysroot)
52 : Headers(HS), Verbose(verbose), IncludeSysroot(sysroot),
53 HasSysroot(!(sysroot.empty() || sysroot ==
"/")) {
59 bool AddPath(
const Twine &Path, IncludeDirGroup Group,
bool isFramework);
64 bool AddUnmappedPath(
const Twine &Path, IncludeDirGroup Group,
69 void AddSystemHeaderPrefix(StringRef Prefix,
bool IsSystemHeader) {
70 SystemHeaderPrefixes.emplace_back(Prefix, IsSystemHeader);
76 bool AddGnuCPlusPlusIncludePaths(StringRef
Base, StringRef ArchDir,
77 StringRef Dir32, StringRef Dir64,
78 const llvm::Triple &triple);
82 void AddMinGWCPlusPlusIncludePaths(StringRef
Base,
87 void AddDefaultCIncludePaths(
const llvm::Triple &triple,
92 void AddDefaultCPlusPlusIncludePaths(
const LangOptions &LangOpts,
93 const llvm::Triple &triple,
98 void AddDefaultIncludePaths(
const LangOptions &Lang,
99 const llvm::Triple &triple,
111 return !Path.empty() && llvm::sys::path::is_separator(Path[0]);
113 return llvm::sys::path::is_absolute(Path);
117 bool InitHeaderSearch::AddPath(
const Twine &Path,
IncludeDirGroup Group,
123 StringRef MappedPathStr = Path.toStringRef(MappedPathStorage);
125 return AddUnmappedPath(IncludeSysroot + Path, Group, isFramework);
129 return AddUnmappedPath(Path, Group, isFramework);
132 bool InitHeaderSearch::AddUnmappedPath(
const Twine &Path,
IncludeDirGroup Group,
134 assert(!Path.isTriviallyEmpty() &&
"can't handle empty path here");
138 StringRef MappedPathStr = Path.toStringRef(MappedPathStorage);
141 if (HasSysroot && (MappedPathStr.startswith(
"/usr/include") ||
142 MappedPathStr.startswith(
"/usr/local/include"))) {
143 Headers.getDiags().Report(diag::warn_poison_system_directories)
158 if (
auto DE = FM.getOptionalDirectoryRef(MappedPathStr)) {
159 IncludePath.push_back(
167 if (
auto FE = FM.getFile(MappedPathStr)) {
168 if (
const HeaderMap *HM = Headers.CreateHeaderMap(*FE)) {
170 IncludePath.push_back(
171 std::make_pair(Group,
179 llvm::errs() <<
"ignoring nonexistent directory \"" 180 << MappedPathStr <<
"\"\n";
184 bool InitHeaderSearch::AddGnuCPlusPlusIncludePaths(StringRef
Base,
188 const llvm::Triple &triple) {
190 bool IsBaseFound = AddPath(Base,
CXXSystem,
false);
193 llvm::Triple::ArchType arch = triple.getArch();
194 bool is64bit = arch == llvm::Triple::ppc64 || arch == llvm::Triple::x86_64;
196 AddPath(Base +
"/" + ArchDir +
"/" + Dir64,
CXXSystem,
false);
198 AddPath(Base +
"/" + ArchDir +
"/" + Dir32,
CXXSystem,
false);
201 AddPath(Base +
"/backward",
CXXSystem,
false);
205 void InitHeaderSearch::AddMinGWCPlusPlusIncludePaths(StringRef Base,
208 AddPath(Base +
"/" + Arch +
"/" + Version +
"/include/c++",
210 AddPath(Base +
"/" + Arch +
"/" + Version +
"/include/c++/" + Arch,
212 AddPath(Base +
"/" + Arch +
"/" + Version +
"/include/c++/backward",
216 void InitHeaderSearch::AddDefaultCIncludePaths(
const llvm::Triple &triple,
218 llvm::Triple::OSType os = triple.getOS();
220 if (triple.isOSDarwin()) {
221 llvm_unreachable(
"Include management is handled in the driver.");
226 case llvm::Triple::CloudABI:
227 case llvm::Triple::FreeBSD:
228 case llvm::Triple::NetBSD:
229 case llvm::Triple::OpenBSD:
230 case llvm::Triple::NaCl:
231 case llvm::Triple::PS4:
232 case llvm::Triple::ELFIAMCU:
233 case llvm::Triple::Fuchsia:
235 case llvm::Triple::Win32:
236 if (triple.getEnvironment() != llvm::Triple::Cygnus)
241 AddPath(
"/usr/local/include",
System,
false);
252 llvm::sys::path::append(P,
"include");
262 StringRef CIncludeDirs(C_INCLUDE_DIRS);
263 if (CIncludeDirs !=
"") {
265 CIncludeDirs.split(dirs,
":");
266 for (StringRef dir : dirs)
272 case llvm::Triple::Linux:
273 case llvm::Triple::Hurd:
274 case llvm::Triple::Solaris:
275 llvm_unreachable(
"Include management is handled in the driver.");
277 case llvm::Triple::CloudABI: {
280 llvm::sys::path::append(P,
"../../..", triple.str(),
"include");
281 AddPath(P,
System,
false);
285 case llvm::Triple::Haiku:
286 AddPath(
"/boot/system/non-packaged/develop/headers",
System,
false);
287 AddPath(
"/boot/system/develop/headers/os",
System,
false);
288 AddPath(
"/boot/system/develop/headers/os/app",
System,
false);
289 AddPath(
"/boot/system/develop/headers/os/arch",
System,
false);
290 AddPath(
"/boot/system/develop/headers/os/device",
System,
false);
291 AddPath(
"/boot/system/develop/headers/os/drivers",
System,
false);
292 AddPath(
"/boot/system/develop/headers/os/game",
System,
false);
293 AddPath(
"/boot/system/develop/headers/os/interface",
System,
false);
294 AddPath(
"/boot/system/develop/headers/os/kernel",
System,
false);
295 AddPath(
"/boot/system/develop/headers/os/locale",
System,
false);
296 AddPath(
"/boot/system/develop/headers/os/mail",
System,
false);
297 AddPath(
"/boot/system/develop/headers/os/media",
System,
false);
298 AddPath(
"/boot/system/develop/headers/os/midi",
System,
false);
299 AddPath(
"/boot/system/develop/headers/os/midi2",
System,
false);
300 AddPath(
"/boot/system/develop/headers/os/net",
System,
false);
301 AddPath(
"/boot/system/develop/headers/os/opengl",
System,
false);
302 AddPath(
"/boot/system/develop/headers/os/storage",
System,
false);
303 AddPath(
"/boot/system/develop/headers/os/support",
System,
false);
304 AddPath(
"/boot/system/develop/headers/os/translation",
System,
false);
305 AddPath(
"/boot/system/develop/headers/os/add-ons/graphics",
System,
false);
306 AddPath(
"/boot/system/develop/headers/os/add-ons/input_server",
System,
false);
307 AddPath(
"/boot/system/develop/headers/os/add-ons/mail_daemon",
System,
false);
308 AddPath(
"/boot/system/develop/headers/os/add-ons/registrar",
System,
false);
309 AddPath(
"/boot/system/develop/headers/os/add-ons/screen_saver",
System,
false);
310 AddPath(
"/boot/system/develop/headers/os/add-ons/tracker",
System,
false);
311 AddPath(
"/boot/system/develop/headers/os/be_apps/Deskbar",
System,
false);
312 AddPath(
"/boot/system/develop/headers/os/be_apps/NetPositive",
System,
false);
313 AddPath(
"/boot/system/develop/headers/os/be_apps/Tracker",
System,
false);
314 AddPath(
"/boot/system/develop/headers/3rdparty",
System,
false);
315 AddPath(
"/boot/system/develop/headers/bsd",
System,
false);
316 AddPath(
"/boot/system/develop/headers/glibc",
System,
false);
317 AddPath(
"/boot/system/develop/headers/posix",
System,
false);
318 AddPath(
"/boot/system/develop/headers",
System,
false);
320 case llvm::Triple::RTEMS:
322 case llvm::Triple::Win32:
323 switch (triple.getEnvironment()) {
324 default: llvm_unreachable(
"Include management is handled in the driver.");
325 case llvm::Triple::Cygnus:
326 AddPath(
"/usr/include/w32api",
System,
false);
328 case llvm::Triple::GNU:
337 case llvm::Triple::CloudABI:
338 case llvm::Triple::RTEMS:
339 case llvm::Triple::NaCl:
340 case llvm::Triple::ELFIAMCU:
341 case llvm::Triple::Fuchsia:
343 case llvm::Triple::PS4: {
345 std::string BaseSDKPath =
"";
347 const char *envValue = getenv(
"SCE_ORBIS_SDK_DIR");
349 BaseSDKPath = envValue;
357 llvm::sys::path::append(P,
"../../..");
358 BaseSDKPath = P.str();
361 AddPath(BaseSDKPath +
"/target/include",
System,
false);
362 if (triple.isPS4CPU())
363 AddPath(BaseSDKPath +
"/target/include_common",
System,
false);
372 void InitHeaderSearch::AddDefaultCPlusPlusIncludePaths(
373 const LangOptions &LangOpts,
const llvm::Triple &triple,
375 llvm::Triple::OSType os = triple.getOS();
378 if (triple.isOSDarwin()) {
379 llvm_unreachable(
"Include management is handled in the driver.");
383 case llvm::Triple::Linux:
384 case llvm::Triple::Hurd:
385 case llvm::Triple::Solaris:
386 llvm_unreachable(
"Include management is handled in the driver.");
388 case llvm::Triple::Win32:
389 switch (triple.getEnvironment()) {
390 default: llvm_unreachable(
"Include management is handled in the driver.");
391 case llvm::Triple::Cygnus:
393 AddMinGWCPlusPlusIncludePaths(
"/usr/lib/gcc",
"i686-pc-cygwin",
"4.7.3");
394 AddMinGWCPlusPlusIncludePaths(
"/usr/lib/gcc",
"i686-pc-cygwin",
"4.5.3");
395 AddMinGWCPlusPlusIncludePaths(
"/usr/lib/gcc",
"i686-pc-cygwin",
"4.3.4");
397 AddMinGWCPlusPlusIncludePaths(
"/usr/lib/gcc",
"i686-pc-cygwin",
"4.3.2");
401 case llvm::Triple::DragonFly:
402 AddPath(
"/usr/include/c++/5.0",
CXXSystem,
false);
404 case llvm::Triple::Minix:
405 AddGnuCPlusPlusIncludePaths(
"/usr/gnu/include/c++/4.4.3",
413 void InitHeaderSearch::AddDefaultIncludePaths(
const LangOptions &Lang,
414 const llvm::Triple &triple,
420 switch (triple.getOS()) {
424 case llvm::Triple::Emscripten:
425 case llvm::Triple::Linux:
426 case llvm::Triple::Hurd:
427 case llvm::Triple::Solaris:
428 case llvm::Triple::WASI:
431 case llvm::Triple::Win32:
432 if (triple.getEnvironment() != llvm::Triple::Cygnus ||
433 triple.isOSBinFormatMachO())
437 case llvm::Triple::UnknownOS:
438 if (triple.getArch() == llvm::Triple::wasm32 ||
439 triple.getArch() == llvm::Triple::wasm64)
445 if (triple.isOSDarwin()) {
448 AddPath(
"/System/Library/Frameworks",
System,
true);
449 AddPath(
"/Library/Frameworks",
System,
true);
454 if (Lang.CPlusPlus && !Lang.AsmPreprocessor &&
457 AddPath(
"/usr/include/c++/v1",
CXXSystem,
false);
459 AddDefaultCPlusPlusIncludePaths(Lang, triple, HSOpts);
463 AddDefaultCIncludePaths(triple, HSOpts);
470 unsigned First,
bool Verbose) {
471 llvm::SmallPtrSet<const DirectoryEntry *, 8> SeenDirs;
472 llvm::SmallPtrSet<const DirectoryEntry *, 8> SeenFrameworkDirs;
473 llvm::SmallPtrSet<const HeaderMap *, 8> SeenHeaderMaps;
474 unsigned NonSystemRemoved = 0;
475 for (
unsigned i = First; i != SearchList.size(); ++i) {
476 unsigned DirToRemove = i;
482 if (SeenDirs.insert(CurEntry.
getDir()).second)
489 assert(CurEntry.
isHeaderMap() &&
"Not a headermap or normal dir?");
491 if (SeenHeaderMaps.insert(CurEntry.
getHeaderMap()).second)
505 for (FirstDir = First;; ++FirstDir) {
506 assert(FirstDir != i &&
"Didn't find dupe?");
520 assert(CurEntry.
isHeaderMap() &&
"Not a headermap or normal dir?");
530 if (SearchList[FirstDir].getDirCharacteristic() ==
SrcMgr::C_User)
531 DirToRemove = FirstDir;
535 llvm::errs() <<
"ignoring duplicate directory \"" 536 << CurEntry.
getName() <<
"\"\n";
537 if (DirToRemove != i)
538 llvm::errs() <<
" as it is a non-system directory that duplicates " 539 <<
"a system directory\n";
541 if (DirToRemove != i)
546 SearchList.erase(SearchList.begin()+DirToRemove);
549 return NonSystemRemoved;
553 void InitHeaderSearch::Realize(
const LangOptions &Lang) {
555 std::vector<DirectoryLookup> SearchList;
556 SearchList.reserve(IncludePath.size());
559 for (
auto &Include : IncludePath)
560 if (Include.first ==
Quoted)
561 SearchList.push_back(Include.second);
565 unsigned NumQuoted = SearchList.size();
567 for (
auto &Include : IncludePath)
569 SearchList.push_back(Include.second);
572 unsigned NumAngled = SearchList.size();
574 for (
auto &Include : IncludePath)
576 (!Lang.ObjC && !Lang.CPlusPlus && Include.first ==
CSystem) ||
579 (Lang.ObjC && !Lang.CPlusPlus && Include.first ==
ObjCSystem) ||
580 (Lang.ObjC && Lang.CPlusPlus && Include.first ==
ObjCXXSystem))
581 SearchList.push_back(Include.second);
583 for (
auto &Include : IncludePath)
584 if (Include.first ==
After)
585 SearchList.push_back(Include.second);
590 unsigned NonSystemRemoved =
RemoveDuplicates(SearchList, NumQuoted, Verbose);
591 NumAngled -= NonSystemRemoved;
593 bool DontSearchCurDir =
false;
594 Headers.SetSearchPaths(SearchList, NumQuoted, NumAngled, DontSearchCurDir);
596 Headers.SetSystemHeaderPrefixes(SystemHeaderPrefixes);
600 llvm::errs() <<
"#include \"...\" search starts here:\n";
601 for (
unsigned i = 0, e = SearchList.size(); i != e; ++i) {
603 llvm::errs() <<
"#include <...> search starts here:\n";
604 StringRef Name = SearchList[i].getName();
606 if (SearchList[i].isNormalDir())
608 else if (SearchList[i].isFramework())
609 Suffix =
" (framework directory)";
611 assert(SearchList[i].isHeaderMap() &&
"Unknown DirectoryLookup");
612 Suffix =
" (headermap)";
614 llvm::errs() <<
" " << Name << Suffix <<
"\n";
616 llvm::errs() <<
"End of search list.\n";
623 const llvm::Triple &Triple) {
627 for (
unsigned i = 0, e = HSOpts.
UserEntries.size(); i != e; ++i) {
636 Init.AddDefaultIncludePaths(Lang, Triple, HSOpts);
645 llvm::sys::path::append(P,
"include");
Paths for '#include <>' added by '-I'.
Implements support for file system lookup, file system caching, and directory search management...
Defines the clang::FileManager interface and associated types.
Like System, but headers are implicitly wrapped in extern "C".
Like System, but only used for C++.
The base class of the type hierarchy.
Like System, but only used for ObjC++.
StringRef getName() const
getName - Return the directory or filename corresponding to this lookup object.
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
Like System, but searched after the system directories.
bool isHeaderMap() const
isHeaderMap - Return true if this is a header map, not a normal directory.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
llvm::ErrorOr< const DirectoryEntry * > getDirectory(StringRef DirName, bool CacheFailure=true)
Lookup, cache, and verify the specified directory (real or virtual).
Defines the clang::LangOptions interface.
IncludeDirGroup
IncludeDirGroup - Identifies the group an include Entry belongs to, representing its relative positiv...
bool isNormalDir() const
isNormalDir - Return true if this is a normal directory, not a header map.
bool isFramework() const
isFramework - True if this is a framework directory.
DirectoryLookup - This class represents one entry in the search list that specifies the search order ...
void setBuiltinIncludeDir(const DirectoryEntry *Dir)
Set the directory that contains Clang-supplied include files, such as our stdarg.h or tgmath...
void ApplyHeaderSearchOptions(HeaderSearch &HS, const HeaderSearchOptions &HSOpts, const LangOptions &Lang, const llvm::Triple &triple)
Apply the header search options to get given HeaderSearch object.
LookupType_t getLookupType() const
getLookupType - Return the kind of directory lookup that this is: either a normal directory...
SrcMgr::CharacteristicKind getDirCharacteristic() const
DirCharacteristic - The type of directory this is, one of the DirType enum values.
Like System, but only used for ObjC.
'#include ""' paths, added by 'gcc -iquote'.
const HeaderMap * getHeaderMap() const
getHeaderMap - Return the directory that this entry refers to.
Like Angled, but marks system directories.
Dataflow Directional Tag Classes.
Like System, but only used for C.
const DirectoryEntry * getDir() const
getDir - Return the directory that this entry refers to.
Like Angled, but marks header maps used when building frameworks.
const DirectoryEntry * getFrameworkDir() const
getFrameworkDir - Return the directory that this framework refers to.