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::OpenBSD: {
437 std::string t = triple.getTriple();
438 if (t.substr(0, 6) ==
"x86_64")
439 t.replace(0, 6,
"amd64");
440 AddGnuCPlusPlusIncludePaths(
"/usr/include/g++",
444 case llvm::Triple::Minix:
445 AddGnuCPlusPlusIncludePaths(
"/usr/gnu/include/c++/4.4.3",
453 void InitHeaderSearch::AddDefaultIncludePaths(
const LangOptions &Lang,
454 const llvm::Triple &triple,
460 switch (triple.getOS()) {
464 case llvm::Triple::Linux:
465 case llvm::Triple::Hurd:
466 case llvm::Triple::Solaris:
469 case llvm::Triple::Win32:
470 if (triple.getEnvironment() != llvm::Triple::Cygnus ||
471 triple.isOSBinFormatMachO())
476 if (Lang.CPlusPlus && !Lang.AsmPreprocessor &&
479 AddPath(
"/usr/include/c++/v1",
CXXSystem,
false);
481 AddDefaultCPlusPlusIncludePaths(Lang, triple, HSOpts);
485 AddDefaultCIncludePaths(triple, HSOpts);
489 if (triple.isOSDarwin()) {
490 AddPath(
"/System/Library/Frameworks",
System,
true);
491 AddPath(
"/Library/Frameworks",
System,
true);
500 unsigned First,
bool Verbose) {
501 llvm::SmallPtrSet<const DirectoryEntry *, 8> SeenDirs;
502 llvm::SmallPtrSet<const DirectoryEntry *, 8> SeenFrameworkDirs;
503 llvm::SmallPtrSet<const HeaderMap *, 8> SeenHeaderMaps;
504 unsigned NonSystemRemoved = 0;
505 for (
unsigned i = First; i != SearchList.size(); ++i) {
506 unsigned DirToRemove = i;
512 if (SeenDirs.insert(CurEntry.
getDir()).second)
519 assert(CurEntry.
isHeaderMap() &&
"Not a headermap or normal dir?");
521 if (SeenHeaderMaps.insert(CurEntry.
getHeaderMap()).second)
535 for (FirstDir = First;; ++FirstDir) {
536 assert(FirstDir != i &&
"Didn't find dupe?");
550 assert(CurEntry.
isHeaderMap() &&
"Not a headermap or normal dir?");
560 if (SearchList[FirstDir].getDirCharacteristic() ==
SrcMgr::C_User)
561 DirToRemove = FirstDir;
565 llvm::errs() <<
"ignoring duplicate directory \"" 566 << CurEntry.
getName() <<
"\"\n";
567 if (DirToRemove != i)
568 llvm::errs() <<
" as it is a non-system directory that duplicates " 569 <<
"a system directory\n";
571 if (DirToRemove != i)
576 SearchList.erase(SearchList.begin()+DirToRemove);
579 return NonSystemRemoved;
583 void InitHeaderSearch::Realize(
const LangOptions &Lang) {
585 std::vector<DirectoryLookup> SearchList;
586 SearchList.reserve(IncludePath.size());
589 for (
auto &Include : IncludePath)
590 if (Include.first ==
Quoted)
591 SearchList.push_back(Include.second);
595 unsigned NumQuoted = SearchList.size();
597 for (
auto &Include : IncludePath)
599 SearchList.push_back(Include.second);
602 unsigned NumAngled = SearchList.size();
604 for (
auto &Include : IncludePath)
606 (!Lang.ObjC && !Lang.CPlusPlus && Include.first ==
CSystem) ||
609 (Lang.ObjC && !Lang.CPlusPlus && Include.first ==
ObjCSystem) ||
610 (Lang.ObjC && Lang.CPlusPlus && Include.first ==
ObjCXXSystem))
611 SearchList.push_back(Include.second);
613 for (
auto &Include : IncludePath)
614 if (Include.first ==
After)
615 SearchList.push_back(Include.second);
620 unsigned NonSystemRemoved =
RemoveDuplicates(SearchList, NumQuoted, Verbose);
621 NumAngled -= NonSystemRemoved;
623 bool DontSearchCurDir =
false;
624 Headers.SetSearchPaths(SearchList, NumQuoted, NumAngled, DontSearchCurDir);
626 Headers.SetSystemHeaderPrefixes(SystemHeaderPrefixes);
630 llvm::errs() <<
"#include \"...\" search starts here:\n";
631 for (
unsigned i = 0, e = SearchList.size(); i != e; ++i) {
633 llvm::errs() <<
"#include <...> search starts here:\n";
634 StringRef Name = SearchList[i].getName();
636 if (SearchList[i].isNormalDir())
638 else if (SearchList[i].isFramework())
639 Suffix =
" (framework directory)";
641 assert(SearchList[i].isHeaderMap() &&
"Unknown DirectoryLookup");
642 Suffix =
" (headermap)";
644 llvm::errs() <<
" " << Name << Suffix <<
"\n";
646 llvm::errs() <<
"End of search list.\n";
653 const llvm::Triple &Triple) {
657 for (
unsigned i = 0, e = HSOpts.
UserEntries.size(); i != e; ++i) {
666 Init.AddDefaultIncludePaths(Lang, Triple, HSOpts);
675 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.