17 #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/FileSystem.h"
29 #include "llvm/Support/Path.h"
30 #include "llvm/Support/raw_ostream.h"
32 using namespace clang;
33 using namespace clang::frontend;
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 ==
"/")) {
59 void AddPath(
const Twine &Path,
IncludeDirGroup Group,
bool isFramework);
68 void AddSystemHeaderPrefix(StringRef Prefix,
bool IsSystemHeader) {
69 SystemHeaderPrefixes.emplace_back(Prefix, IsSystemHeader);
74 void AddGnuCPlusPlusIncludePaths(StringRef
Base,
78 const llvm::Triple &triple);
82 void AddMinGWCPlusPlusIncludePaths(StringRef
Base,
87 void AddDefaultCIncludePaths(
const llvm::Triple &triple,
92 void AddDefaultCPlusPlusIncludePaths(
const llvm::Triple &triple,
97 void AddDefaultIncludePaths(
const LangOptions &Lang,
98 const llvm::Triple &triple,
109 #if defined(LLVM_ON_WIN32)
110 return !Path.empty() && llvm::sys::path::is_separator(Path[0]);
112 return llvm::sys::path::is_absolute(Path);
116 void InitHeaderSearch::AddPath(
const Twine &Path,
IncludeDirGroup Group,
122 StringRef MappedPathStr = Path.toStringRef(MappedPathStorage);
124 AddUnmappedPath(IncludeSysroot + Path, Group, isFramework);
129 AddUnmappedPath(Path, Group, isFramework);
132 void 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";
176 void InitHeaderSearch::AddGnuCPlusPlusIncludePaths(StringRef
Base,
180 const llvm::Triple &triple) {
185 llvm::Triple::ArchType arch = triple.getArch();
186 bool is64bit = arch == llvm::Triple::ppc64 || arch == llvm::Triple::x86_64;
188 AddPath(Base +
"/" + ArchDir +
"/" + Dir64,
CXXSystem,
false);
190 AddPath(Base +
"/" + ArchDir +
"/" + Dir32,
CXXSystem,
false);
193 AddPath(Base +
"/backward",
CXXSystem,
false);
196 void InitHeaderSearch::AddMinGWCPlusPlusIncludePaths(StringRef Base,
199 AddPath(Base +
"/" + Arch +
"/" + Version +
"/include/c++",
201 AddPath(Base +
"/" + Arch +
"/" + Version +
"/include/c++/" + Arch,
203 AddPath(Base +
"/" + Arch +
"/" + Version +
"/include/c++/backward",
207 void InitHeaderSearch::AddDefaultCIncludePaths(
const llvm::Triple &triple,
209 llvm::Triple::OSType os = triple.getOS();
213 case llvm::Triple::CloudABI:
214 case llvm::Triple::FreeBSD:
215 case llvm::Triple::NetBSD:
216 case llvm::Triple::OpenBSD:
217 case llvm::Triple::Bitrig:
218 case llvm::Triple::NaCl:
219 case llvm::Triple::PS4:
220 case llvm::Triple::ELFIAMCU:
222 case llvm::Triple::Win32:
223 if (triple.getEnvironment() != llvm::Triple::Cygnus)
227 AddPath(
"/usr/local/include",
System,
false);
238 llvm::sys::path::append(P,
"include");
248 StringRef CIncludeDirs(C_INCLUDE_DIRS);
249 if (CIncludeDirs !=
"") {
251 CIncludeDirs.split(dirs,
":");
252 for (StringRef dir : dirs)
258 case llvm::Triple::Linux:
259 llvm_unreachable(
"Include management is handled in the driver.");
261 case llvm::Triple::CloudABI: {
264 llvm::sys::path::append(P,
"../../..", triple.str(),
"include");
265 AddPath(P,
System,
false);
269 case llvm::Triple::Haiku:
270 AddPath(
"/boot/system/non-packaged/develop/headers",
System,
false);
271 AddPath(
"/boot/system/develop/headers/os",
System,
false);
272 AddPath(
"/boot/system/develop/headers/os/app",
System,
false);
273 AddPath(
"/boot/system/develop/headers/os/arch",
System,
false);
274 AddPath(
"/boot/system/develop/headers/os/device",
System,
false);
275 AddPath(
"/boot/system/develop/headers/os/drivers",
System,
false);
276 AddPath(
"/boot/system/develop/headers/os/game",
System,
false);
277 AddPath(
"/boot/system/develop/headers/os/interface",
System,
false);
278 AddPath(
"/boot/system/develop/headers/os/kernel",
System,
false);
279 AddPath(
"/boot/system/develop/headers/os/locale",
System,
false);
280 AddPath(
"/boot/system/develop/headers/os/mail",
System,
false);
281 AddPath(
"/boot/system/develop/headers/os/media",
System,
false);
282 AddPath(
"/boot/system/develop/headers/os/midi",
System,
false);
283 AddPath(
"/boot/system/develop/headers/os/midi2",
System,
false);
284 AddPath(
"/boot/system/develop/headers/os/net",
System,
false);
285 AddPath(
"/boot/system/develop/headers/os/opengl",
System,
false);
286 AddPath(
"/boot/system/develop/headers/os/storage",
System,
false);
287 AddPath(
"/boot/system/develop/headers/os/support",
System,
false);
288 AddPath(
"/boot/system/develop/headers/os/translation",
System,
false);
289 AddPath(
"/boot/system/develop/headers/os/add-ons/graphics",
System,
false);
290 AddPath(
"/boot/system/develop/headers/os/add-ons/input_server",
System,
false);
291 AddPath(
"/boot/system/develop/headers/os/add-ons/mail_daemon",
System,
false);
292 AddPath(
"/boot/system/develop/headers/os/add-ons/registrar",
System,
false);
293 AddPath(
"/boot/system/develop/headers/os/add-ons/screen_saver",
System,
false);
294 AddPath(
"/boot/system/develop/headers/os/add-ons/tracker",
System,
false);
295 AddPath(
"/boot/system/develop/headers/os/be_apps/Deskbar",
System,
false);
296 AddPath(
"/boot/system/develop/headers/os/be_apps/NetPositive",
System,
false);
297 AddPath(
"/boot/system/develop/headers/os/be_apps/Tracker",
System,
false);
298 AddPath(
"/boot/system/develop/headers/3rdparty",
System,
false);
299 AddPath(
"/boot/system/develop/headers/bsd",
System,
false);
300 AddPath(
"/boot/system/develop/headers/glibc",
System,
false);
301 AddPath(
"/boot/system/develop/headers/posix",
System,
false);
302 AddPath(
"/boot/system/develop/headers",
System,
false);
304 case llvm::Triple::RTEMS:
306 case llvm::Triple::Win32:
307 switch (triple.getEnvironment()) {
308 default: llvm_unreachable(
"Include management is handled in the driver.");
309 case llvm::Triple::Cygnus:
310 AddPath(
"/usr/include/w32api",
System,
false);
312 case llvm::Triple::GNU:
321 case llvm::Triple::CloudABI:
322 case llvm::Triple::RTEMS:
323 case llvm::Triple::NaCl:
324 case llvm::Triple::ELFIAMCU:
326 case llvm::Triple::PS4: {
328 std::string BaseSDKPath =
"";
330 const char *envValue = getenv(
"SCE_ORBIS_SDK_DIR");
332 BaseSDKPath = envValue;
340 llvm::sys::path::append(P,
"../../..");
341 BaseSDKPath = P.str();
344 AddPath(BaseSDKPath +
"/target/include",
System,
false);
345 if (triple.isPS4CPU())
346 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 = 0; ; ++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);
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";
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".
SrcMgr::CharacteristicKind getDirCharacteristic() const
DirCharacteristic - The type of directory this is, one of the DirType enum values.
Like System, but only used for C++.
The base class of the type hierarchy.
Like System, but only used for ObjC++.
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.
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
bool isFramework() const
isFramework - True if this is a framework 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).
const HeaderMap * getHeaderMap() const
getHeaderMap - Return the directory that this entry refers to.
Defines the clang::LangOptions interface.
StringRef getName() const
Return the actual identifier string.
IncludeDirGroup
IncludeDirGroup - Identifies the group an include Entry belongs to, representing its relative positiv...
LookupType_t getLookupType() const
getLookupType - Return the kind of directory lookup that this is: either a normal directory...
bool isNormalDir() const
isNormalDir - Return true if this is a normal directory, not a header map.
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.
const DirectoryEntry * getFrameworkDir() const
getFrameworkDir - Return the directory that this framework refers to.
Cached information about one file (either on disk or in the virtual file system). ...
Like System, but only used for ObjC.
'#include ""' paths, added by 'gcc -iquote'.
Like System, but only used for C.
detail::InMemoryDirectory::const_iterator E
const char * getName() const
getName - Return the directory or filename corresponding to this lookup object.
Cached information about one directory (either on disk or in the virtual file system).
bool isHeaderMap() const
isHeaderMap - Return true if this is a header map, not a normal directory.
Like Angled, but marks header maps used when.
const DirectoryEntry * getDir() const
getDir - Return the directory that this entry refers to.