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::Hurd:
264 case llvm::Triple::Solaris:
265 llvm_unreachable(
"Include management is handled in the driver.");
267 case llvm::Triple::CloudABI: {
270 llvm::sys::path::append(P,
"../../..", triple.str(),
"include");
271 AddPath(P,
System,
false);
275 case llvm::Triple::Haiku:
276 AddPath(
"/boot/system/non-packaged/develop/headers",
System,
false);
277 AddPath(
"/boot/system/develop/headers/os",
System,
false);
278 AddPath(
"/boot/system/develop/headers/os/app",
System,
false);
279 AddPath(
"/boot/system/develop/headers/os/arch",
System,
false);
280 AddPath(
"/boot/system/develop/headers/os/device",
System,
false);
281 AddPath(
"/boot/system/develop/headers/os/drivers",
System,
false);
282 AddPath(
"/boot/system/develop/headers/os/game",
System,
false);
283 AddPath(
"/boot/system/develop/headers/os/interface",
System,
false);
284 AddPath(
"/boot/system/develop/headers/os/kernel",
System,
false);
285 AddPath(
"/boot/system/develop/headers/os/locale",
System,
false);
286 AddPath(
"/boot/system/develop/headers/os/mail",
System,
false);
287 AddPath(
"/boot/system/develop/headers/os/media",
System,
false);
288 AddPath(
"/boot/system/develop/headers/os/midi",
System,
false);
289 AddPath(
"/boot/system/develop/headers/os/midi2",
System,
false);
290 AddPath(
"/boot/system/develop/headers/os/net",
System,
false);
291 AddPath(
"/boot/system/develop/headers/os/opengl",
System,
false);
292 AddPath(
"/boot/system/develop/headers/os/storage",
System,
false);
293 AddPath(
"/boot/system/develop/headers/os/support",
System,
false);
294 AddPath(
"/boot/system/develop/headers/os/translation",
System,
false);
295 AddPath(
"/boot/system/develop/headers/os/add-ons/graphics",
System,
false);
296 AddPath(
"/boot/system/develop/headers/os/add-ons/input_server",
System,
false);
297 AddPath(
"/boot/system/develop/headers/os/add-ons/mail_daemon",
System,
false);
298 AddPath(
"/boot/system/develop/headers/os/add-ons/registrar",
System,
false);
299 AddPath(
"/boot/system/develop/headers/os/add-ons/screen_saver",
System,
false);
300 AddPath(
"/boot/system/develop/headers/os/add-ons/tracker",
System,
false);
301 AddPath(
"/boot/system/develop/headers/os/be_apps/Deskbar",
System,
false);
302 AddPath(
"/boot/system/develop/headers/os/be_apps/NetPositive",
System,
false);
303 AddPath(
"/boot/system/develop/headers/os/be_apps/Tracker",
System,
false);
304 AddPath(
"/boot/system/develop/headers/3rdparty",
System,
false);
305 AddPath(
"/boot/system/develop/headers/bsd",
System,
false);
306 AddPath(
"/boot/system/develop/headers/glibc",
System,
false);
307 AddPath(
"/boot/system/develop/headers/posix",
System,
false);
308 AddPath(
"/boot/system/develop/headers",
System,
false);
310 case llvm::Triple::RTEMS:
312 case llvm::Triple::Win32:
313 switch (triple.getEnvironment()) {
314 default: llvm_unreachable(
"Include management is handled in the driver.");
315 case llvm::Triple::Cygnus:
316 AddPath(
"/usr/include/w32api",
System,
false);
318 case llvm::Triple::GNU:
327 case llvm::Triple::CloudABI:
328 case llvm::Triple::RTEMS:
329 case llvm::Triple::NaCl:
330 case llvm::Triple::ELFIAMCU:
331 case llvm::Triple::Fuchsia:
333 case llvm::Triple::PS4: {
335 std::string BaseSDKPath =
"";
337 const char *envValue = getenv(
"SCE_ORBIS_SDK_DIR");
339 BaseSDKPath = envValue;
347 llvm::sys::path::append(P,
"../../..");
348 BaseSDKPath = P.str();
351 AddPath(BaseSDKPath +
"/target/include",
System,
false);
352 if (triple.isPS4CPU())
353 AddPath(BaseSDKPath +
"/target/include_common",
System,
false);
362 void InitHeaderSearch::AddDefaultCPlusPlusIncludePaths(
363 const LangOptions &LangOpts,
const llvm::Triple &triple,
365 llvm::Triple::OSType os = triple.getOS();
368 if (triple.isOSDarwin()) {
369 bool IsBaseFound =
true;
370 switch (triple.getArch()) {
373 case llvm::Triple::ppc:
374 case llvm::Triple::ppc64:
375 IsBaseFound = AddGnuCPlusPlusIncludePaths(
"/usr/include/c++/4.2.1",
376 "powerpc-apple-darwin10",
"",
378 IsBaseFound |= AddGnuCPlusPlusIncludePaths(
"/usr/include/c++/4.0.0",
379 "powerpc-apple-darwin10",
"",
383 case llvm::Triple::x86:
384 case llvm::Triple::x86_64:
385 IsBaseFound = AddGnuCPlusPlusIncludePaths(
"/usr/include/c++/4.2.1",
386 "i686-apple-darwin10",
"",
388 IsBaseFound |= AddGnuCPlusPlusIncludePaths(
389 "/usr/include/c++/4.0.0",
"i686-apple-darwin8",
"",
"", triple);
392 case llvm::Triple::arm:
393 case llvm::Triple::thumb:
394 IsBaseFound = AddGnuCPlusPlusIncludePaths(
395 "/usr/include/c++/4.2.1",
"arm-apple-darwin10",
"v7",
"", triple);
396 IsBaseFound |= AddGnuCPlusPlusIncludePaths(
397 "/usr/include/c++/4.2.1",
"arm-apple-darwin10",
"v6",
"", triple);
400 case llvm::Triple::aarch64:
401 IsBaseFound = AddGnuCPlusPlusIncludePaths(
402 "/usr/include/c++/4.2.1",
"arm64-apple-darwin10",
"",
"", triple);
407 !(LangOpts.CUDA || LangOpts.OpenCL || LangOpts.RenderScript)) {
409 diag::warn_stdlibcxx_not_found);
415 case llvm::Triple::Linux:
416 case llvm::Triple::Hurd:
417 case llvm::Triple::Solaris:
418 llvm_unreachable(
"Include management is handled in the driver.");
420 case llvm::Triple::Win32:
421 switch (triple.getEnvironment()) {
422 default: llvm_unreachable(
"Include management is handled in the driver.");
423 case llvm::Triple::Cygnus:
425 AddMinGWCPlusPlusIncludePaths(
"/usr/lib/gcc",
"i686-pc-cygwin",
"4.7.3");
426 AddMinGWCPlusPlusIncludePaths(
"/usr/lib/gcc",
"i686-pc-cygwin",
"4.5.3");
427 AddMinGWCPlusPlusIncludePaths(
"/usr/lib/gcc",
"i686-pc-cygwin",
"4.3.4");
429 AddMinGWCPlusPlusIncludePaths(
"/usr/lib/gcc",
"i686-pc-cygwin",
"4.3.2");
433 case llvm::Triple::DragonFly:
434 AddPath(
"/usr/include/c++/5.0",
CXXSystem,
false);
436 case llvm::Triple::Minix:
437 AddGnuCPlusPlusIncludePaths(
"/usr/gnu/include/c++/4.4.3",
445 void InitHeaderSearch::AddDefaultIncludePaths(
const LangOptions &Lang,
446 const llvm::Triple &triple,
452 switch (triple.getOS()) {
456 case llvm::Triple::Linux:
457 case llvm::Triple::Hurd:
458 case llvm::Triple::Solaris:
461 case llvm::Triple::Win32:
462 if (triple.getEnvironment() != llvm::Triple::Cygnus ||
463 triple.isOSBinFormatMachO())
468 if (Lang.CPlusPlus && !Lang.AsmPreprocessor &&
471 AddPath(
"/usr/include/c++/v1",
CXXSystem,
false);
473 AddDefaultCPlusPlusIncludePaths(Lang, triple, HSOpts);
477 AddDefaultCIncludePaths(triple, HSOpts);
481 if (triple.isOSDarwin()) {
482 AddPath(
"/System/Library/Frameworks",
System,
true);
483 AddPath(
"/Library/Frameworks",
System,
true);
492 unsigned First,
bool Verbose) {
493 llvm::SmallPtrSet<const DirectoryEntry *, 8> SeenDirs;
494 llvm::SmallPtrSet<const DirectoryEntry *, 8> SeenFrameworkDirs;
495 llvm::SmallPtrSet<const HeaderMap *, 8> SeenHeaderMaps;
496 unsigned NonSystemRemoved = 0;
497 for (
unsigned i = First; i != SearchList.size(); ++i) {
498 unsigned DirToRemove = i;
504 if (SeenDirs.insert(CurEntry.
getDir()).second)
511 assert(CurEntry.
isHeaderMap() &&
"Not a headermap or normal dir?");
513 if (SeenHeaderMaps.insert(CurEntry.
getHeaderMap()).second)
527 for (FirstDir = First;; ++FirstDir) {
528 assert(FirstDir != i &&
"Didn't find dupe?");
542 assert(CurEntry.
isHeaderMap() &&
"Not a headermap or normal dir?");
552 if (SearchList[FirstDir].getDirCharacteristic() ==
SrcMgr::C_User)
553 DirToRemove = FirstDir;
557 llvm::errs() <<
"ignoring duplicate directory \"" 558 << CurEntry.
getName() <<
"\"\n";
559 if (DirToRemove != i)
560 llvm::errs() <<
" as it is a non-system directory that duplicates " 561 <<
"a system directory\n";
563 if (DirToRemove != i)
568 SearchList.erase(SearchList.begin()+DirToRemove);
571 return NonSystemRemoved;
575 void InitHeaderSearch::Realize(
const LangOptions &Lang) {
577 std::vector<DirectoryLookup> SearchList;
578 SearchList.reserve(IncludePath.size());
581 for (
auto &Include : IncludePath)
582 if (Include.first ==
Quoted)
583 SearchList.push_back(Include.second);
587 unsigned NumQuoted = SearchList.size();
589 for (
auto &Include : IncludePath)
591 SearchList.push_back(Include.second);
594 unsigned NumAngled = SearchList.size();
596 for (
auto &Include : IncludePath)
598 (!Lang.ObjC && !Lang.CPlusPlus && Include.first ==
CSystem) ||
601 (Lang.ObjC && !Lang.CPlusPlus && Include.first ==
ObjCSystem) ||
602 (Lang.ObjC && Lang.CPlusPlus && Include.first ==
ObjCXXSystem))
603 SearchList.push_back(Include.second);
605 for (
auto &Include : IncludePath)
606 if (Include.first ==
After)
607 SearchList.push_back(Include.second);
612 unsigned NonSystemRemoved =
RemoveDuplicates(SearchList, NumQuoted, Verbose);
613 NumAngled -= NonSystemRemoved;
615 bool DontSearchCurDir =
false;
616 Headers.SetSearchPaths(SearchList, NumQuoted, NumAngled, DontSearchCurDir);
618 Headers.SetSystemHeaderPrefixes(SystemHeaderPrefixes);
622 llvm::errs() <<
"#include \"...\" search starts here:\n";
623 for (
unsigned i = 0, e = SearchList.size(); i != e; ++i) {
625 llvm::errs() <<
"#include <...> search starts here:\n";
626 StringRef Name = SearchList[i].getName();
628 if (SearchList[i].isNormalDir())
630 else if (SearchList[i].isFramework())
631 Suffix =
" (framework directory)";
633 assert(SearchList[i].isHeaderMap() &&
"Unknown DirectoryLookup");
634 Suffix =
" (headermap)";
636 llvm::errs() <<
" " << Name << Suffix <<
"\n";
638 llvm::errs() <<
"End of search list.\n";
645 const llvm::Triple &Triple) {
649 for (
unsigned i = 0, e = HSOpts.
UserEntries.size(); i != e; ++i) {
658 Init.AddDefaultIncludePaths(Lang, Triple, HSOpts);
667 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.