16 #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 ==
"/")) {
58 void AddPath(
const Twine &Path, IncludeDirGroup Group,
bool isFramework);
62 void AddUnmappedPath(
const Twine &Path, IncludeDirGroup Group,
67 void AddSystemHeaderPrefix(StringRef Prefix,
bool IsSystemHeader) {
68 SystemHeaderPrefixes.emplace_back(Prefix, IsSystemHeader);
73 void AddGnuCPlusPlusIncludePaths(StringRef
Base,
77 const llvm::Triple &triple);
81 void AddMinGWCPlusPlusIncludePaths(StringRef
Base,
86 void AddDefaultCIncludePaths(
const llvm::Triple &triple,
91 void AddDefaultCPlusPlusIncludePaths(
const llvm::Triple &triple,
96 void AddDefaultIncludePaths(
const LangOptions &Lang,
97 const llvm::Triple &triple,
108 #if defined(LLVM_ON_WIN32) 109 return !Path.empty() && llvm::sys::path::is_separator(Path[0]);
111 return llvm::sys::path::is_absolute(Path);
115 void InitHeaderSearch::AddPath(
const Twine &Path,
IncludeDirGroup Group,
121 StringRef MappedPathStr = Path.toStringRef(MappedPathStorage);
123 AddUnmappedPath(IncludeSysroot + Path, Group, isFramework);
128 AddUnmappedPath(Path, Group, isFramework);
131 void InitHeaderSearch::AddUnmappedPath(
const Twine &Path,
IncludeDirGroup Group,
133 assert(!Path.isTriviallyEmpty() &&
"can't handle empty path here");
137 StringRef MappedPathStr = Path.toStringRef(MappedPathStorage);
151 IncludePath.push_back(
159 if (
const FileEntry *FE = FM.getFile(MappedPathStr)) {
160 if (
const HeaderMap *HM = Headers.CreateHeaderMap(FE)) {
162 IncludePath.push_back(
163 std::make_pair(Group,
171 llvm::errs() <<
"ignoring nonexistent directory \"" 172 << MappedPathStr <<
"\"\n";
175 void InitHeaderSearch::AddGnuCPlusPlusIncludePaths(StringRef
Base,
179 const llvm::Triple &triple) {
184 llvm::Triple::ArchType arch = triple.getArch();
185 bool is64bit = arch == llvm::Triple::ppc64 || arch == llvm::Triple::x86_64;
187 AddPath(Base +
"/" + ArchDir +
"/" + Dir64,
CXXSystem,
false);
189 AddPath(Base +
"/" + ArchDir +
"/" + Dir32,
CXXSystem,
false);
192 AddPath(Base +
"/backward",
CXXSystem,
false);
195 void InitHeaderSearch::AddMinGWCPlusPlusIncludePaths(StringRef Base,
198 AddPath(Base +
"/" + Arch +
"/" + Version +
"/include/c++",
200 AddPath(Base +
"/" + Arch +
"/" + Version +
"/include/c++/" + Arch,
202 AddPath(Base +
"/" + Arch +
"/" + Version +
"/include/c++/backward",
206 void InitHeaderSearch::AddDefaultCIncludePaths(
const llvm::Triple &triple,
208 llvm::Triple::OSType os = triple.getOS();
212 case llvm::Triple::CloudABI:
213 case llvm::Triple::FreeBSD:
214 case llvm::Triple::NetBSD:
215 case llvm::Triple::OpenBSD:
216 case llvm::Triple::NaCl:
217 case llvm::Triple::PS4:
218 case llvm::Triple::ELFIAMCU:
220 case llvm::Triple::Win32:
221 if (triple.getEnvironment() != llvm::Triple::Cygnus)
226 AddPath(
"/usr/local/include",
System,
false);
237 llvm::sys::path::append(P,
"include");
247 StringRef CIncludeDirs(C_INCLUDE_DIRS);
248 if (CIncludeDirs !=
"") {
250 CIncludeDirs.split(dirs,
":");
251 for (StringRef dir : dirs)
257 case llvm::Triple::Linux:
258 llvm_unreachable(
"Include management is handled in the driver.");
260 case llvm::Triple::CloudABI: {
263 llvm::sys::path::append(P,
"../../..", triple.str(),
"include");
264 AddPath(P,
System,
false);
268 case llvm::Triple::Haiku:
269 AddPath(
"/boot/system/non-packaged/develop/headers",
System,
false);
270 AddPath(
"/boot/system/develop/headers/os",
System,
false);
271 AddPath(
"/boot/system/develop/headers/os/app",
System,
false);
272 AddPath(
"/boot/system/develop/headers/os/arch",
System,
false);
273 AddPath(
"/boot/system/develop/headers/os/device",
System,
false);
274 AddPath(
"/boot/system/develop/headers/os/drivers",
System,
false);
275 AddPath(
"/boot/system/develop/headers/os/game",
System,
false);
276 AddPath(
"/boot/system/develop/headers/os/interface",
System,
false);
277 AddPath(
"/boot/system/develop/headers/os/kernel",
System,
false);
278 AddPath(
"/boot/system/develop/headers/os/locale",
System,
false);
279 AddPath(
"/boot/system/develop/headers/os/mail",
System,
false);
280 AddPath(
"/boot/system/develop/headers/os/media",
System,
false);
281 AddPath(
"/boot/system/develop/headers/os/midi",
System,
false);
282 AddPath(
"/boot/system/develop/headers/os/midi2",
System,
false);
283 AddPath(
"/boot/system/develop/headers/os/net",
System,
false);
284 AddPath(
"/boot/system/develop/headers/os/opengl",
System,
false);
285 AddPath(
"/boot/system/develop/headers/os/storage",
System,
false);
286 AddPath(
"/boot/system/develop/headers/os/support",
System,
false);
287 AddPath(
"/boot/system/develop/headers/os/translation",
System,
false);
288 AddPath(
"/boot/system/develop/headers/os/add-ons/graphics",
System,
false);
289 AddPath(
"/boot/system/develop/headers/os/add-ons/input_server",
System,
false);
290 AddPath(
"/boot/system/develop/headers/os/add-ons/mail_daemon",
System,
false);
291 AddPath(
"/boot/system/develop/headers/os/add-ons/registrar",
System,
false);
292 AddPath(
"/boot/system/develop/headers/os/add-ons/screen_saver",
System,
false);
293 AddPath(
"/boot/system/develop/headers/os/add-ons/tracker",
System,
false);
294 AddPath(
"/boot/system/develop/headers/os/be_apps/Deskbar",
System,
false);
295 AddPath(
"/boot/system/develop/headers/os/be_apps/NetPositive",
System,
false);
296 AddPath(
"/boot/system/develop/headers/os/be_apps/Tracker",
System,
false);
297 AddPath(
"/boot/system/develop/headers/3rdparty",
System,
false);
298 AddPath(
"/boot/system/develop/headers/bsd",
System,
false);
299 AddPath(
"/boot/system/develop/headers/glibc",
System,
false);
300 AddPath(
"/boot/system/develop/headers/posix",
System,
false);
301 AddPath(
"/boot/system/develop/headers",
System,
false);
303 case llvm::Triple::RTEMS:
305 case llvm::Triple::Win32:
306 switch (triple.getEnvironment()) {
307 default: llvm_unreachable(
"Include management is handled in the driver.");
308 case llvm::Triple::Cygnus:
309 AddPath(
"/usr/include/w32api",
System,
false);
311 case llvm::Triple::GNU:
320 case llvm::Triple::CloudABI:
321 case llvm::Triple::RTEMS:
322 case llvm::Triple::NaCl:
323 case llvm::Triple::ELFIAMCU:
325 case llvm::Triple::PS4: {
327 std::string BaseSDKPath =
"";
329 const char *envValue = getenv(
"SCE_ORBIS_SDK_DIR");
331 BaseSDKPath = envValue;
339 llvm::sys::path::append(P,
"../../..");
340 BaseSDKPath = P.str();
343 AddPath(BaseSDKPath +
"/target/include",
System,
false);
344 if (triple.isPS4CPU())
345 AddPath(BaseSDKPath +
"/target/include_common",
System,
false);
354 void InitHeaderSearch::
355 AddDefaultCPlusPlusIncludePaths(
const llvm::Triple &triple,
const HeaderSearchOptions &HSOpts) {
356 llvm::Triple::OSType os = triple.getOS();
359 if (triple.isOSDarwin()) {
360 switch (triple.getArch()) {
363 case llvm::Triple::ppc:
364 case llvm::Triple::ppc64:
365 AddGnuCPlusPlusIncludePaths(
"/usr/include/c++/4.2.1",
366 "powerpc-apple-darwin10",
"",
"ppc64",
368 AddGnuCPlusPlusIncludePaths(
"/usr/include/c++/4.0.0",
369 "powerpc-apple-darwin10",
"",
"ppc64",
373 case llvm::Triple::x86:
374 case llvm::Triple::x86_64:
375 AddGnuCPlusPlusIncludePaths(
"/usr/include/c++/4.2.1",
376 "i686-apple-darwin10",
"",
"x86_64", triple);
377 AddGnuCPlusPlusIncludePaths(
"/usr/include/c++/4.0.0",
378 "i686-apple-darwin8",
"",
"", triple);
381 case llvm::Triple::arm:
382 case llvm::Triple::thumb:
383 AddGnuCPlusPlusIncludePaths(
"/usr/include/c++/4.2.1",
384 "arm-apple-darwin10",
"v7",
"", triple);
385 AddGnuCPlusPlusIncludePaths(
"/usr/include/c++/4.2.1",
386 "arm-apple-darwin10",
"v6",
"", triple);
389 case llvm::Triple::aarch64:
390 AddGnuCPlusPlusIncludePaths(
"/usr/include/c++/4.2.1",
391 "arm64-apple-darwin10",
"",
"", triple);
398 case llvm::Triple::Linux:
399 llvm_unreachable(
"Include management is handled in the driver.");
401 case llvm::Triple::Win32:
402 switch (triple.getEnvironment()) {
403 default: llvm_unreachable(
"Include management is handled in the driver.");
404 case llvm::Triple::Cygnus:
406 AddMinGWCPlusPlusIncludePaths(
"/usr/lib/gcc",
"i686-pc-cygwin",
"4.7.3");
407 AddMinGWCPlusPlusIncludePaths(
"/usr/lib/gcc",
"i686-pc-cygwin",
"4.5.3");
408 AddMinGWCPlusPlusIncludePaths(
"/usr/lib/gcc",
"i686-pc-cygwin",
"4.3.4");
410 AddMinGWCPlusPlusIncludePaths(
"/usr/lib/gcc",
"i686-pc-cygwin",
"4.3.2");
414 case llvm::Triple::DragonFly:
415 AddPath(
"/usr/include/c++/5.0",
CXXSystem,
false);
417 case llvm::Triple::OpenBSD: {
418 std::string t = triple.getTriple();
419 if (t.substr(0, 6) ==
"x86_64")
420 t.replace(0, 6,
"amd64");
421 AddGnuCPlusPlusIncludePaths(
"/usr/include/g++",
425 case llvm::Triple::Minix:
426 AddGnuCPlusPlusIncludePaths(
"/usr/gnu/include/c++/4.4.3",
434 void InitHeaderSearch::AddDefaultIncludePaths(
const LangOptions &Lang,
435 const llvm::Triple &triple,
441 switch (triple.getOS()) {
445 case llvm::Triple::Linux:
448 case llvm::Triple::Win32:
449 if (triple.getEnvironment() != llvm::Triple::Cygnus ||
450 triple.isOSBinFormatMachO())
458 if (triple.isOSDarwin()) {
463 StringRef NoVer = llvm::sys::path::parent_path(HSOpts.
ResourceDir);
465 StringRef Lib = llvm::sys::path::parent_path(NoVer);
470 llvm::sys::path::append(P,
"include",
"c++",
"v1");
474 AddPath(
"/usr/include/c++/v1",
CXXSystem,
false);
476 AddDefaultCPlusPlusIncludePaths(triple, HSOpts);
480 AddDefaultCIncludePaths(triple, HSOpts);
484 if (triple.isOSDarwin()) {
485 AddPath(
"/System/Library/Frameworks",
System,
true);
486 AddPath(
"/Library/Frameworks",
System,
true);
495 unsigned First,
bool Verbose) {
496 llvm::SmallPtrSet<const DirectoryEntry *, 8> SeenDirs;
497 llvm::SmallPtrSet<const DirectoryEntry *, 8> SeenFrameworkDirs;
498 llvm::SmallPtrSet<const HeaderMap *, 8> SeenHeaderMaps;
499 unsigned NonSystemRemoved = 0;
500 for (
unsigned i = First; i != SearchList.size(); ++i) {
501 unsigned DirToRemove = i;
507 if (SeenDirs.insert(CurEntry.
getDir()).second)
514 assert(CurEntry.
isHeaderMap() &&
"Not a headermap or normal dir?");
516 if (SeenHeaderMaps.insert(CurEntry.
getHeaderMap()).second)
530 for (FirstDir = First;; ++FirstDir) {
531 assert(FirstDir != i &&
"Didn't find dupe?");
545 assert(CurEntry.
isHeaderMap() &&
"Not a headermap or normal dir?");
555 if (SearchList[FirstDir].getDirCharacteristic() ==
SrcMgr::C_User)
556 DirToRemove = FirstDir;
560 llvm::errs() <<
"ignoring duplicate directory \"" 561 << CurEntry.
getName() <<
"\"\n";
562 if (DirToRemove != i)
563 llvm::errs() <<
" as it is a non-system directory that duplicates " 564 <<
"a system directory\n";
566 if (DirToRemove != i)
571 SearchList.erase(SearchList.begin()+DirToRemove);
574 return NonSystemRemoved;
578 void InitHeaderSearch::Realize(
const LangOptions &Lang) {
580 std::vector<DirectoryLookup> SearchList;
581 SearchList.reserve(IncludePath.size());
584 for (
auto &Include : IncludePath)
585 if (Include.first ==
Quoted)
586 SearchList.push_back(Include.second);
590 unsigned NumQuoted = SearchList.size();
592 for (
auto &Include : IncludePath)
594 SearchList.push_back(Include.second);
597 unsigned NumAngled = SearchList.size();
599 for (
auto &Include : IncludePath)
601 (!Lang.ObjC1 && !Lang.CPlusPlus && Include.first ==
CSystem) ||
604 (Lang.ObjC1 && !Lang.CPlusPlus && Include.first ==
ObjCSystem) ||
605 (Lang.ObjC1 && Lang.CPlusPlus && Include.first ==
ObjCXXSystem))
606 SearchList.push_back(Include.second);
608 for (
auto &Include : IncludePath)
609 if (Include.first ==
After)
610 SearchList.push_back(Include.second);
615 unsigned NonSystemRemoved =
RemoveDuplicates(SearchList, NumQuoted, Verbose);
616 NumAngled -= NonSystemRemoved;
618 bool DontSearchCurDir =
false;
619 Headers.SetSearchPaths(SearchList, NumQuoted, NumAngled, DontSearchCurDir);
621 Headers.SetSystemHeaderPrefixes(SystemHeaderPrefixes);
625 llvm::errs() <<
"#include \"...\" search starts here:\n";
626 for (
unsigned i = 0, e = SearchList.size(); i != e; ++i) {
628 llvm::errs() <<
"#include <...> search starts here:\n";
629 StringRef Name = SearchList[i].getName();
631 if (SearchList[i].isNormalDir())
633 else if (SearchList[i].isFramework())
634 Suffix =
" (framework directory)";
636 assert(SearchList[i].isHeaderMap() &&
"Unknown DirectoryLookup");
637 Suffix =
" (headermap)";
639 llvm::errs() <<
" " << Name << Suffix <<
"\n";
641 llvm::errs() <<
"End of search list.\n";
648 const llvm::Triple &Triple) {
652 for (
unsigned i = 0, e = HSOpts.
UserEntries.size(); i != e; ++i) {
661 Init.AddDefaultIncludePaths(Lang, Triple, HSOpts);
670 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.