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);
152 IncludePath.push_back(
160 if (
const FileEntry *FE = FM.getFile(MappedPathStr)) {
161 if (
const HeaderMap *HM = Headers.CreateHeaderMap(FE)) {
163 IncludePath.push_back(
164 std::make_pair(Group,
172 llvm::errs() <<
"ignoring nonexistent directory \"" 173 << MappedPathStr <<
"\"\n";
177 bool InitHeaderSearch::AddGnuCPlusPlusIncludePaths(StringRef
Base,
181 const llvm::Triple &triple) {
183 bool IsBaseFound = AddPath(Base,
CXXSystem,
false);
186 llvm::Triple::ArchType arch = triple.getArch();
187 bool is64bit = arch == llvm::Triple::ppc64 || arch == llvm::Triple::x86_64;
189 AddPath(Base +
"/" + ArchDir +
"/" + Dir64,
CXXSystem,
false);
191 AddPath(Base +
"/" + ArchDir +
"/" + Dir32,
CXXSystem,
false);
194 AddPath(Base +
"/backward",
CXXSystem,
false);
198 void InitHeaderSearch::AddMinGWCPlusPlusIncludePaths(StringRef Base,
201 AddPath(Base +
"/" + Arch +
"/" + Version +
"/include/c++",
203 AddPath(Base +
"/" + Arch +
"/" + Version +
"/include/c++/" + Arch,
205 AddPath(Base +
"/" + Arch +
"/" + Version +
"/include/c++/backward",
209 void InitHeaderSearch::AddDefaultCIncludePaths(
const llvm::Triple &triple,
211 llvm::Triple::OSType os = triple.getOS();
213 if (triple.isOSDarwin()) {
214 llvm_unreachable(
"Include management is handled in the driver.");
219 case llvm::Triple::CloudABI:
220 case llvm::Triple::FreeBSD:
221 case llvm::Triple::NetBSD:
222 case llvm::Triple::OpenBSD:
223 case llvm::Triple::NaCl:
224 case llvm::Triple::PS4:
225 case llvm::Triple::ELFIAMCU:
226 case llvm::Triple::Fuchsia:
228 case llvm::Triple::Win32:
229 if (triple.getEnvironment() != llvm::Triple::Cygnus)
234 AddPath(
"/usr/local/include",
System,
false);
245 llvm::sys::path::append(P,
"include");
255 StringRef CIncludeDirs(C_INCLUDE_DIRS);
256 if (CIncludeDirs !=
"") {
258 CIncludeDirs.split(dirs,
":");
259 for (StringRef dir : dirs)
265 case llvm::Triple::Linux:
266 case llvm::Triple::Hurd:
267 case llvm::Triple::Solaris:
268 llvm_unreachable(
"Include management is handled in the driver.");
270 case llvm::Triple::CloudABI: {
273 llvm::sys::path::append(P,
"../../..", triple.str(),
"include");
274 AddPath(P,
System,
false);
278 case llvm::Triple::Haiku:
279 AddPath(
"/boot/system/non-packaged/develop/headers",
System,
false);
280 AddPath(
"/boot/system/develop/headers/os",
System,
false);
281 AddPath(
"/boot/system/develop/headers/os/app",
System,
false);
282 AddPath(
"/boot/system/develop/headers/os/arch",
System,
false);
283 AddPath(
"/boot/system/develop/headers/os/device",
System,
false);
284 AddPath(
"/boot/system/develop/headers/os/drivers",
System,
false);
285 AddPath(
"/boot/system/develop/headers/os/game",
System,
false);
286 AddPath(
"/boot/system/develop/headers/os/interface",
System,
false);
287 AddPath(
"/boot/system/develop/headers/os/kernel",
System,
false);
288 AddPath(
"/boot/system/develop/headers/os/locale",
System,
false);
289 AddPath(
"/boot/system/develop/headers/os/mail",
System,
false);
290 AddPath(
"/boot/system/develop/headers/os/media",
System,
false);
291 AddPath(
"/boot/system/develop/headers/os/midi",
System,
false);
292 AddPath(
"/boot/system/develop/headers/os/midi2",
System,
false);
293 AddPath(
"/boot/system/develop/headers/os/net",
System,
false);
294 AddPath(
"/boot/system/develop/headers/os/opengl",
System,
false);
295 AddPath(
"/boot/system/develop/headers/os/storage",
System,
false);
296 AddPath(
"/boot/system/develop/headers/os/support",
System,
false);
297 AddPath(
"/boot/system/develop/headers/os/translation",
System,
false);
298 AddPath(
"/boot/system/develop/headers/os/add-ons/graphics",
System,
false);
299 AddPath(
"/boot/system/develop/headers/os/add-ons/input_server",
System,
false);
300 AddPath(
"/boot/system/develop/headers/os/add-ons/mail_daemon",
System,
false);
301 AddPath(
"/boot/system/develop/headers/os/add-ons/registrar",
System,
false);
302 AddPath(
"/boot/system/develop/headers/os/add-ons/screen_saver",
System,
false);
303 AddPath(
"/boot/system/develop/headers/os/add-ons/tracker",
System,
false);
304 AddPath(
"/boot/system/develop/headers/os/be_apps/Deskbar",
System,
false);
305 AddPath(
"/boot/system/develop/headers/os/be_apps/NetPositive",
System,
false);
306 AddPath(
"/boot/system/develop/headers/os/be_apps/Tracker",
System,
false);
307 AddPath(
"/boot/system/develop/headers/3rdparty",
System,
false);
308 AddPath(
"/boot/system/develop/headers/bsd",
System,
false);
309 AddPath(
"/boot/system/develop/headers/glibc",
System,
false);
310 AddPath(
"/boot/system/develop/headers/posix",
System,
false);
311 AddPath(
"/boot/system/develop/headers",
System,
false);
313 case llvm::Triple::RTEMS:
315 case llvm::Triple::Win32:
316 switch (triple.getEnvironment()) {
317 default: llvm_unreachable(
"Include management is handled in the driver.");
318 case llvm::Triple::Cygnus:
319 AddPath(
"/usr/include/w32api",
System,
false);
321 case llvm::Triple::GNU:
330 case llvm::Triple::CloudABI:
331 case llvm::Triple::RTEMS:
332 case llvm::Triple::NaCl:
333 case llvm::Triple::ELFIAMCU:
334 case llvm::Triple::Fuchsia:
336 case llvm::Triple::PS4: {
338 std::string BaseSDKPath =
"";
340 const char *envValue = getenv(
"SCE_ORBIS_SDK_DIR");
342 BaseSDKPath = envValue;
350 llvm::sys::path::append(P,
"../../..");
351 BaseSDKPath = P.str();
354 AddPath(BaseSDKPath +
"/target/include",
System,
false);
355 if (triple.isPS4CPU())
356 AddPath(BaseSDKPath +
"/target/include_common",
System,
false);
365 void InitHeaderSearch::AddDefaultCPlusPlusIncludePaths(
366 const LangOptions &LangOpts,
const llvm::Triple &triple,
368 llvm::Triple::OSType os = triple.getOS();
371 if (triple.isOSDarwin()) {
372 llvm_unreachable(
"Include management is handled in the driver.");
376 case llvm::Triple::Linux:
377 case llvm::Triple::Hurd:
378 case llvm::Triple::Solaris:
379 llvm_unreachable(
"Include management is handled in the driver.");
381 case llvm::Triple::Win32:
382 switch (triple.getEnvironment()) {
383 default: llvm_unreachable(
"Include management is handled in the driver.");
384 case llvm::Triple::Cygnus:
386 AddMinGWCPlusPlusIncludePaths(
"/usr/lib/gcc",
"i686-pc-cygwin",
"4.7.3");
387 AddMinGWCPlusPlusIncludePaths(
"/usr/lib/gcc",
"i686-pc-cygwin",
"4.5.3");
388 AddMinGWCPlusPlusIncludePaths(
"/usr/lib/gcc",
"i686-pc-cygwin",
"4.3.4");
390 AddMinGWCPlusPlusIncludePaths(
"/usr/lib/gcc",
"i686-pc-cygwin",
"4.3.2");
394 case llvm::Triple::DragonFly:
395 AddPath(
"/usr/include/c++/5.0",
CXXSystem,
false);
397 case llvm::Triple::Minix:
398 AddGnuCPlusPlusIncludePaths(
"/usr/gnu/include/c++/4.4.3",
406 void InitHeaderSearch::AddDefaultIncludePaths(
const LangOptions &Lang,
407 const llvm::Triple &triple,
413 switch (triple.getOS()) {
417 case llvm::Triple::Emscripten:
418 case llvm::Triple::Linux:
419 case llvm::Triple::Hurd:
420 case llvm::Triple::Solaris:
421 case llvm::Triple::WASI:
424 case llvm::Triple::Win32:
425 if (triple.getEnvironment() != llvm::Triple::Cygnus ||
426 triple.isOSBinFormatMachO())
430 case llvm::Triple::UnknownOS:
431 if (triple.getArch() == llvm::Triple::wasm32 ||
432 triple.getArch() == llvm::Triple::wasm64)
438 if (triple.isOSDarwin()) {
441 AddPath(
"/System/Library/Frameworks",
System,
true);
442 AddPath(
"/Library/Frameworks",
System,
true);
447 if (Lang.CPlusPlus && !Lang.AsmPreprocessor &&
450 AddPath(
"/usr/include/c++/v1",
CXXSystem,
false);
452 AddDefaultCPlusPlusIncludePaths(Lang, triple, HSOpts);
456 AddDefaultCIncludePaths(triple, HSOpts);
463 unsigned First,
bool Verbose) {
464 llvm::SmallPtrSet<const DirectoryEntry *, 8> SeenDirs;
465 llvm::SmallPtrSet<const DirectoryEntry *, 8> SeenFrameworkDirs;
466 llvm::SmallPtrSet<const HeaderMap *, 8> SeenHeaderMaps;
467 unsigned NonSystemRemoved = 0;
468 for (
unsigned i = First;
i != SearchList.size(); ++
i) {
469 unsigned DirToRemove =
i;
475 if (SeenDirs.insert(CurEntry.
getDir()).second)
482 assert(CurEntry.
isHeaderMap() &&
"Not a headermap or normal dir?");
484 if (SeenHeaderMaps.insert(CurEntry.
getHeaderMap()).second)
498 for (FirstDir = First;; ++FirstDir) {
499 assert(FirstDir !=
i &&
"Didn't find dupe?");
513 assert(CurEntry.
isHeaderMap() &&
"Not a headermap or normal dir?");
523 if (SearchList[FirstDir].getDirCharacteristic() ==
SrcMgr::C_User)
524 DirToRemove = FirstDir;
528 llvm::errs() <<
"ignoring duplicate directory \"" 529 << CurEntry.
getName() <<
"\"\n";
530 if (DirToRemove !=
i)
531 llvm::errs() <<
" as it is a non-system directory that duplicates " 532 <<
"a system directory\n";
534 if (DirToRemove !=
i)
539 SearchList.erase(SearchList.begin()+DirToRemove);
542 return NonSystemRemoved;
546 void InitHeaderSearch::Realize(
const LangOptions &Lang) {
548 std::vector<DirectoryLookup> SearchList;
549 SearchList.reserve(IncludePath.size());
552 for (
auto &Include : IncludePath)
553 if (Include.first ==
Quoted)
554 SearchList.push_back(Include.second);
558 unsigned NumQuoted = SearchList.size();
560 for (
auto &Include : IncludePath)
562 SearchList.push_back(Include.second);
565 unsigned NumAngled = SearchList.size();
567 for (
auto &Include : IncludePath)
569 (!Lang.ObjC && !Lang.CPlusPlus && Include.first ==
CSystem) ||
572 (Lang.ObjC && !Lang.CPlusPlus && Include.first ==
ObjCSystem) ||
573 (Lang.ObjC && Lang.CPlusPlus && Include.first ==
ObjCXXSystem))
574 SearchList.push_back(Include.second);
576 for (
auto &Include : IncludePath)
577 if (Include.first ==
After)
578 SearchList.push_back(Include.second);
583 unsigned NonSystemRemoved =
RemoveDuplicates(SearchList, NumQuoted, Verbose);
584 NumAngled -= NonSystemRemoved;
586 bool DontSearchCurDir =
false;
587 Headers.SetSearchPaths(SearchList, NumQuoted, NumAngled, DontSearchCurDir);
589 Headers.SetSystemHeaderPrefixes(SystemHeaderPrefixes);
593 llvm::errs() <<
"#include \"...\" search starts here:\n";
594 for (
unsigned i = 0, e = SearchList.size();
i != e; ++
i) {
596 llvm::errs() <<
"#include <...> search starts here:\n";
597 StringRef Name = SearchList[
i].getName();
599 if (SearchList[
i].isNormalDir())
601 else if (SearchList[
i].isFramework())
602 Suffix =
" (framework directory)";
604 assert(SearchList[
i].isHeaderMap() &&
"Unknown DirectoryLookup");
605 Suffix =
" (headermap)";
607 llvm::errs() <<
" " << Name << Suffix <<
"\n";
609 llvm::errs() <<
"End of search list.\n";
616 const llvm::Triple &Triple) {
620 for (
unsigned i = 0, e = HSOpts.
UserEntries.size();
i != e; ++
i) {
629 Init.AddDefaultIncludePaths(Lang, Triple, HSOpts);
638 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.
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.