16 #include "clang/Config/config.h" 22 #include "llvm/ADT/SmallPtrSet.h" 23 #include "llvm/ADT/SmallString.h" 24 #include "llvm/ADT/SmallVector.h" 25 #include "llvm/ADT/StringExtras.h" 26 #include "llvm/ADT/Triple.h" 27 #include "llvm/ADT/Twine.h" 28 #include "llvm/Support/ErrorHandling.h" 29 #include "llvm/Support/Path.h" 30 #include "llvm/Support/raw_ostream.h" 32 using namespace clang;
40 class InitHeaderSearch {
41 std::vector<std::pair<IncludeDirGroup, DirectoryLookup> > IncludePath;
44 std::vector<std::pair<std::string, bool> > SystemHeaderPrefixes;
47 std::string IncludeSysroot;
52 InitHeaderSearch(
HeaderSearch &HS,
bool verbose, StringRef sysroot)
53 : Headers(HS), Verbose(verbose), IncludeSysroot(sysroot),
54 HasSysroot(!(sysroot.empty() || sysroot ==
"/")) {
60 bool AddPath(
const Twine &Path, IncludeDirGroup Group,
bool isFramework);
65 bool AddUnmappedPath(
const Twine &Path, IncludeDirGroup Group,
70 void AddSystemHeaderPrefix(StringRef Prefix,
bool IsSystemHeader) {
71 SystemHeaderPrefixes.emplace_back(Prefix, IsSystemHeader);
77 bool AddGnuCPlusPlusIncludePaths(StringRef
Base, StringRef ArchDir,
78 StringRef Dir32, StringRef Dir64,
79 const llvm::Triple &triple);
83 void AddMinGWCPlusPlusIncludePaths(StringRef
Base,
88 void AddDefaultCIncludePaths(
const llvm::Triple &triple,
93 void AddDefaultCPlusPlusIncludePaths(
const LangOptions &LangOpts,
94 const llvm::Triple &triple,
99 void AddDefaultIncludePaths(
const LangOptions &Lang,
100 const llvm::Triple &triple,
112 return !Path.empty() && llvm::sys::path::is_separator(Path[0]);
114 return llvm::sys::path::is_absolute(Path);
118 bool InitHeaderSearch::AddPath(
const Twine &Path,
IncludeDirGroup Group,
124 StringRef MappedPathStr = Path.toStringRef(MappedPathStorage);
126 return AddUnmappedPath(IncludeSysroot + Path, Group, isFramework);
130 return AddUnmappedPath(Path, Group, isFramework);
133 bool InitHeaderSearch::AddUnmappedPath(
const Twine &Path,
IncludeDirGroup Group,
135 assert(!Path.isTriviallyEmpty() &&
"can't handle empty path here");
139 StringRef MappedPathStr = Path.toStringRef(MappedPathStorage);
153 IncludePath.push_back(
161 if (
const FileEntry *FE = FM.getFile(MappedPathStr)) {
162 if (
const HeaderMap *HM = Headers.CreateHeaderMap(FE)) {
164 IncludePath.push_back(
165 std::make_pair(Group,
173 llvm::errs() <<
"ignoring nonexistent directory \"" 174 << MappedPathStr <<
"\"\n";
178 bool InitHeaderSearch::AddGnuCPlusPlusIncludePaths(StringRef
Base,
182 const llvm::Triple &triple) {
184 bool IsBaseFound = AddPath(Base,
CXXSystem,
false);
187 llvm::Triple::ArchType arch = triple.getArch();
188 bool is64bit = arch == llvm::Triple::ppc64 || arch == llvm::Triple::x86_64;
190 AddPath(Base +
"/" + ArchDir +
"/" + Dir64,
CXXSystem,
false);
192 AddPath(Base +
"/" + ArchDir +
"/" + Dir32,
CXXSystem,
false);
195 AddPath(Base +
"/backward",
CXXSystem,
false);
199 void InitHeaderSearch::AddMinGWCPlusPlusIncludePaths(StringRef Base,
202 AddPath(Base +
"/" + Arch +
"/" + Version +
"/include/c++",
204 AddPath(Base +
"/" + Arch +
"/" + Version +
"/include/c++/" + Arch,
206 AddPath(Base +
"/" + Arch +
"/" + Version +
"/include/c++/backward",
210 void InitHeaderSearch::AddDefaultCIncludePaths(
const llvm::Triple &triple,
212 llvm::Triple::OSType os = triple.getOS();
216 case llvm::Triple::CloudABI:
217 case llvm::Triple::FreeBSD:
218 case llvm::Triple::NetBSD:
219 case llvm::Triple::OpenBSD:
220 case llvm::Triple::NaCl:
221 case llvm::Triple::PS4:
222 case llvm::Triple::ELFIAMCU:
223 case llvm::Triple::Fuchsia:
225 case llvm::Triple::Win32:
226 if (triple.getEnvironment() != llvm::Triple::Cygnus)
231 AddPath(
"/usr/local/include",
System,
false);
242 llvm::sys::path::append(P,
"include");
252 StringRef CIncludeDirs(C_INCLUDE_DIRS);
253 if (CIncludeDirs !=
"") {
255 CIncludeDirs.split(dirs,
":");
256 for (StringRef dir : dirs)
262 case llvm::Triple::Linux:
263 case llvm::Triple::Solaris:
264 llvm_unreachable(
"Include management is handled in the driver.");
266 case llvm::Triple::CloudABI: {
269 llvm::sys::path::append(P,
"../../..", triple.str(),
"include");
270 AddPath(P,
System,
false);
274 case llvm::Triple::Haiku:
275 AddPath(
"/boot/system/non-packaged/develop/headers",
System,
false);
276 AddPath(
"/boot/system/develop/headers/os",
System,
false);
277 AddPath(
"/boot/system/develop/headers/os/app",
System,
false);
278 AddPath(
"/boot/system/develop/headers/os/arch",
System,
false);
279 AddPath(
"/boot/system/develop/headers/os/device",
System,
false);
280 AddPath(
"/boot/system/develop/headers/os/drivers",
System,
false);
281 AddPath(
"/boot/system/develop/headers/os/game",
System,
false);
282 AddPath(
"/boot/system/develop/headers/os/interface",
System,
false);
283 AddPath(
"/boot/system/develop/headers/os/kernel",
System,
false);
284 AddPath(
"/boot/system/develop/headers/os/locale",
System,
false);
285 AddPath(
"/boot/system/develop/headers/os/mail",
System,
false);
286 AddPath(
"/boot/system/develop/headers/os/media",
System,
false);
287 AddPath(
"/boot/system/develop/headers/os/midi",
System,
false);
288 AddPath(
"/boot/system/develop/headers/os/midi2",
System,
false);
289 AddPath(
"/boot/system/develop/headers/os/net",
System,
false);
290 AddPath(
"/boot/system/develop/headers/os/opengl",
System,
false);
291 AddPath(
"/boot/system/develop/headers/os/storage",
System,
false);
292 AddPath(
"/boot/system/develop/headers/os/support",
System,
false);
293 AddPath(
"/boot/system/develop/headers/os/translation",
System,
false);
294 AddPath(
"/boot/system/develop/headers/os/add-ons/graphics",
System,
false);
295 AddPath(
"/boot/system/develop/headers/os/add-ons/input_server",
System,
false);
296 AddPath(
"/boot/system/develop/headers/os/add-ons/mail_daemon",
System,
false);
297 AddPath(
"/boot/system/develop/headers/os/add-ons/registrar",
System,
false);
298 AddPath(
"/boot/system/develop/headers/os/add-ons/screen_saver",
System,
false);
299 AddPath(
"/boot/system/develop/headers/os/add-ons/tracker",
System,
false);
300 AddPath(
"/boot/system/develop/headers/os/be_apps/Deskbar",
System,
false);
301 AddPath(
"/boot/system/develop/headers/os/be_apps/NetPositive",
System,
false);
302 AddPath(
"/boot/system/develop/headers/os/be_apps/Tracker",
System,
false);
303 AddPath(
"/boot/system/develop/headers/3rdparty",
System,
false);
304 AddPath(
"/boot/system/develop/headers/bsd",
System,
false);
305 AddPath(
"/boot/system/develop/headers/glibc",
System,
false);
306 AddPath(
"/boot/system/develop/headers/posix",
System,
false);
307 AddPath(
"/boot/system/develop/headers",
System,
false);
309 case llvm::Triple::RTEMS:
311 case llvm::Triple::Win32:
312 switch (triple.getEnvironment()) {
313 default: llvm_unreachable(
"Include management is handled in the driver.");
314 case llvm::Triple::Cygnus:
315 AddPath(
"/usr/include/w32api",
System,
false);
317 case llvm::Triple::GNU:
326 case llvm::Triple::CloudABI:
327 case llvm::Triple::RTEMS:
328 case llvm::Triple::NaCl:
329 case llvm::Triple::ELFIAMCU:
330 case llvm::Triple::Fuchsia:
332 case llvm::Triple::PS4: {
334 std::string BaseSDKPath =
"";
336 const char *envValue = getenv(
"SCE_ORBIS_SDK_DIR");
338 BaseSDKPath = envValue;
346 llvm::sys::path::append(P,
"../../..");
347 BaseSDKPath = P.str();
350 AddPath(BaseSDKPath +
"/target/include",
System,
false);
351 if (triple.isPS4CPU())
352 AddPath(BaseSDKPath +
"/target/include_common",
System,
false);
361 void InitHeaderSearch::AddDefaultCPlusPlusIncludePaths(
362 const LangOptions &LangOpts,
const llvm::Triple &triple,
364 llvm::Triple::OSType os = triple.getOS();
367 if (triple.isOSDarwin()) {
368 bool IsBaseFound =
true;
369 switch (triple.getArch()) {
372 case llvm::Triple::ppc:
373 case llvm::Triple::ppc64:
374 IsBaseFound = AddGnuCPlusPlusIncludePaths(
"/usr/include/c++/4.2.1",
375 "powerpc-apple-darwin10",
"",
377 IsBaseFound |= AddGnuCPlusPlusIncludePaths(
"/usr/include/c++/4.0.0",
378 "powerpc-apple-darwin10",
"",
382 case llvm::Triple::x86:
383 case llvm::Triple::x86_64:
384 IsBaseFound = AddGnuCPlusPlusIncludePaths(
"/usr/include/c++/4.2.1",
385 "i686-apple-darwin10",
"",
387 IsBaseFound |= AddGnuCPlusPlusIncludePaths(
388 "/usr/include/c++/4.0.0",
"i686-apple-darwin8",
"",
"", triple);
391 case llvm::Triple::arm:
392 case llvm::Triple::thumb:
393 IsBaseFound = AddGnuCPlusPlusIncludePaths(
394 "/usr/include/c++/4.2.1",
"arm-apple-darwin10",
"v7",
"", triple);
395 IsBaseFound |= AddGnuCPlusPlusIncludePaths(
396 "/usr/include/c++/4.2.1",
"arm-apple-darwin10",
"v6",
"", triple);
399 case llvm::Triple::aarch64:
400 IsBaseFound = AddGnuCPlusPlusIncludePaths(
401 "/usr/include/c++/4.2.1",
"arm64-apple-darwin10",
"",
"", triple);
406 !(LangOpts.CUDA || LangOpts.OpenCL || LangOpts.RenderScript)) {
408 diag::warn_stdlibcxx_not_found);
414 case llvm::Triple::Linux:
415 case llvm::Triple::Solaris:
416 llvm_unreachable(
"Include management is handled in the driver.");
418 case llvm::Triple::Win32:
419 switch (triple.getEnvironment()) {
420 default: llvm_unreachable(
"Include management is handled in the driver.");
421 case llvm::Triple::Cygnus:
423 AddMinGWCPlusPlusIncludePaths(
"/usr/lib/gcc",
"i686-pc-cygwin",
"4.7.3");
424 AddMinGWCPlusPlusIncludePaths(
"/usr/lib/gcc",
"i686-pc-cygwin",
"4.5.3");
425 AddMinGWCPlusPlusIncludePaths(
"/usr/lib/gcc",
"i686-pc-cygwin",
"4.3.4");
427 AddMinGWCPlusPlusIncludePaths(
"/usr/lib/gcc",
"i686-pc-cygwin",
"4.3.2");
431 case llvm::Triple::DragonFly:
432 AddPath(
"/usr/include/c++/5.0",
CXXSystem,
false);
434 case llvm::Triple::OpenBSD: {
435 std::string t = triple.getTriple();
436 if (t.substr(0, 6) ==
"x86_64")
437 t.replace(0, 6,
"amd64");
438 AddGnuCPlusPlusIncludePaths(
"/usr/include/g++",
442 case llvm::Triple::Minix:
443 AddGnuCPlusPlusIncludePaths(
"/usr/gnu/include/c++/4.4.3",
451 void InitHeaderSearch::AddDefaultIncludePaths(
const LangOptions &Lang,
452 const llvm::Triple &triple,
458 switch (triple.getOS()) {
462 case llvm::Triple::Linux:
463 case llvm::Triple::Solaris:
466 case llvm::Triple::Win32:
467 if (triple.getEnvironment() != llvm::Triple::Cygnus ||
468 triple.isOSBinFormatMachO())
473 if (Lang.CPlusPlus && !Lang.AsmPreprocessor &&
476 if (triple.isOSDarwin()) {
481 StringRef NoVer = llvm::sys::path::parent_path(HSOpts.
ResourceDir);
483 StringRef Lib = llvm::sys::path::parent_path(NoVer);
488 llvm::sys::path::append(P,
"include",
"c++",
"v1");
492 AddPath(
"/usr/include/c++/v1",
CXXSystem,
false);
494 AddDefaultCPlusPlusIncludePaths(Lang, triple, HSOpts);
498 AddDefaultCIncludePaths(triple, HSOpts);
502 if (triple.isOSDarwin()) {
503 AddPath(
"/System/Library/Frameworks",
System,
true);
504 AddPath(
"/Library/Frameworks",
System,
true);
513 unsigned First,
bool Verbose) {
514 llvm::SmallPtrSet<const DirectoryEntry *, 8> SeenDirs;
515 llvm::SmallPtrSet<const DirectoryEntry *, 8> SeenFrameworkDirs;
516 llvm::SmallPtrSet<const HeaderMap *, 8> SeenHeaderMaps;
517 unsigned NonSystemRemoved = 0;
518 for (
unsigned i = First; i != SearchList.size(); ++i) {
519 unsigned DirToRemove = i;
525 if (SeenDirs.insert(CurEntry.
getDir()).second)
532 assert(CurEntry.
isHeaderMap() &&
"Not a headermap or normal dir?");
534 if (SeenHeaderMaps.insert(CurEntry.
getHeaderMap()).second)
548 for (FirstDir = First;; ++FirstDir) {
549 assert(FirstDir != i &&
"Didn't find dupe?");
563 assert(CurEntry.
isHeaderMap() &&
"Not a headermap or normal dir?");
573 if (SearchList[FirstDir].getDirCharacteristic() ==
SrcMgr::C_User)
574 DirToRemove = FirstDir;
578 llvm::errs() <<
"ignoring duplicate directory \"" 579 << CurEntry.
getName() <<
"\"\n";
580 if (DirToRemove != i)
581 llvm::errs() <<
" as it is a non-system directory that duplicates " 582 <<
"a system directory\n";
584 if (DirToRemove != i)
589 SearchList.erase(SearchList.begin()+DirToRemove);
592 return NonSystemRemoved;
596 void InitHeaderSearch::Realize(
const LangOptions &Lang) {
598 std::vector<DirectoryLookup> SearchList;
599 SearchList.reserve(IncludePath.size());
602 for (
auto &Include : IncludePath)
603 if (Include.first ==
Quoted)
604 SearchList.push_back(Include.second);
608 unsigned NumQuoted = SearchList.size();
610 for (
auto &Include : IncludePath)
612 SearchList.push_back(Include.second);
615 unsigned NumAngled = SearchList.size();
617 for (
auto &Include : IncludePath)
619 (!Lang.ObjC1 && !Lang.CPlusPlus && Include.first ==
CSystem) ||
622 (Lang.ObjC1 && !Lang.CPlusPlus && Include.first ==
ObjCSystem) ||
623 (Lang.ObjC1 && Lang.CPlusPlus && Include.first ==
ObjCXXSystem))
624 SearchList.push_back(Include.second);
626 for (
auto &Include : IncludePath)
627 if (Include.first ==
After)
628 SearchList.push_back(Include.second);
633 unsigned NonSystemRemoved =
RemoveDuplicates(SearchList, NumQuoted, Verbose);
634 NumAngled -= NonSystemRemoved;
636 bool DontSearchCurDir =
false;
637 Headers.SetSearchPaths(SearchList, NumQuoted, NumAngled, DontSearchCurDir);
639 Headers.SetSystemHeaderPrefixes(SystemHeaderPrefixes);
643 llvm::errs() <<
"#include \"...\" search starts here:\n";
644 for (
unsigned i = 0, e = SearchList.size(); i != e; ++i) {
646 llvm::errs() <<
"#include <...> search starts here:\n";
647 StringRef Name = SearchList[i].getName();
649 if (SearchList[i].isNormalDir())
651 else if (SearchList[i].isFramework())
652 Suffix =
" (framework directory)";
654 assert(SearchList[i].isHeaderMap() &&
"Unknown DirectoryLookup");
655 Suffix =
" (headermap)";
657 llvm::errs() <<
" " << Name << Suffix <<
"\n";
659 llvm::errs() <<
"End of search list.\n";
666 const llvm::Triple &Triple) {
670 for (
unsigned i = 0, e = HSOpts.
UserEntries.size(); i != e; ++i) {
679 Init.AddDefaultIncludePaths(Lang, Triple, HSOpts);
688 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...
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.
Encodes a location in the source.
LookupType_t getLookupType() const
getLookupType - Return the kind of directory lookup that this is: either a normal directory...
Cached information about one file (either on disk or in the virtual file system). ...
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.
Cached information about one directory (either on disk or in the virtual file system).
Like Angled, but marks header maps used when building frameworks.
const DirectoryEntry * getFrameworkDir() const
getFrameworkDir - Return the directory that this framework refers to.