clang  3.9.0
InitHeaderSearch.cpp
Go to the documentation of this file.
1 //===--- InitHeaderSearch.cpp - Initialize header search paths ------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the InitHeaderSearch class.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "clang/Frontend/Utils.h"
17 #include "clang/Config/config.h" // C_INCLUDE_DIRS
18 #include "clang/Lex/HeaderMap.h"
19 #include "clang/Lex/HeaderSearch.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"
31 
32 using namespace clang;
33 using namespace clang::frontend;
34 
35 namespace {
36 
37 /// InitHeaderSearch - This class makes it easier to set the search paths of
38 /// a HeaderSearch object. InitHeaderSearch stores several search path lists
39 /// internally, which can be sent to a HeaderSearch object in one swoop.
40 class InitHeaderSearch {
41  std::vector<std::pair<IncludeDirGroup, DirectoryLookup> > IncludePath;
42  typedef std::vector<std::pair<IncludeDirGroup,
43  DirectoryLookup> >::const_iterator path_iterator;
44  std::vector<std::pair<std::string, bool> > SystemHeaderPrefixes;
45  HeaderSearch &Headers;
46  bool Verbose;
47  std::string IncludeSysroot;
48  bool HasSysroot;
49 
50 public:
51 
52  InitHeaderSearch(HeaderSearch &HS, bool verbose, StringRef sysroot)
53  : Headers(HS), Verbose(verbose), IncludeSysroot(sysroot),
54  HasSysroot(!(sysroot.empty() || sysroot == "/")) {
55  }
56 
57  /// AddPath - Add the specified path to the specified group list, prefixing
58  /// the sysroot if used.
59  void AddPath(const Twine &Path, IncludeDirGroup Group, bool isFramework);
60 
61  /// AddUnmappedPath - Add the specified path to the specified group list,
62  /// without performing any sysroot remapping.
63  void AddUnmappedPath(const Twine &Path, IncludeDirGroup Group,
64  bool isFramework);
65 
66  /// AddSystemHeaderPrefix - Add the specified prefix to the system header
67  /// prefix list.
68  void AddSystemHeaderPrefix(StringRef Prefix, bool IsSystemHeader) {
69  SystemHeaderPrefixes.emplace_back(Prefix, IsSystemHeader);
70  }
71 
72  /// AddGnuCPlusPlusIncludePaths - Add the necessary paths to support a gnu
73  /// libstdc++.
74  void AddGnuCPlusPlusIncludePaths(StringRef Base,
75  StringRef ArchDir,
76  StringRef Dir32,
77  StringRef Dir64,
78  const llvm::Triple &triple);
79 
80  /// AddMinGWCPlusPlusIncludePaths - Add the necessary paths to support a MinGW
81  /// libstdc++.
82  void AddMinGWCPlusPlusIncludePaths(StringRef Base,
83  StringRef Arch,
84  StringRef Version);
85 
86  // AddDefaultCIncludePaths - Add paths that should always be searched.
87  void AddDefaultCIncludePaths(const llvm::Triple &triple,
88  const HeaderSearchOptions &HSOpts);
89 
90  // AddDefaultCPlusPlusIncludePaths - Add paths that should be searched when
91  // compiling c++.
92  void AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple,
93  const HeaderSearchOptions &HSOpts);
94 
95  /// AddDefaultSystemIncludePaths - Adds the default system include paths so
96  /// that e.g. stdio.h is found.
97  void AddDefaultIncludePaths(const LangOptions &Lang,
98  const llvm::Triple &triple,
99  const HeaderSearchOptions &HSOpts);
100 
101  /// Realize - Merges all search path lists into one list and send it to
102  /// HeaderSearch.
103  void Realize(const LangOptions &Lang);
104 };
105 
106 } // end anonymous namespace.
107 
108 static bool CanPrefixSysroot(StringRef Path) {
109 #if defined(LLVM_ON_WIN32)
110  return !Path.empty() && llvm::sys::path::is_separator(Path[0]);
111 #else
112  return llvm::sys::path::is_absolute(Path);
113 #endif
114 }
115 
116 void InitHeaderSearch::AddPath(const Twine &Path, IncludeDirGroup Group,
117  bool isFramework) {
118  // Add the path with sysroot prepended, if desired and this is a system header
119  // group.
120  if (HasSysroot) {
121  SmallString<256> MappedPathStorage;
122  StringRef MappedPathStr = Path.toStringRef(MappedPathStorage);
123  if (CanPrefixSysroot(MappedPathStr)) {
124  AddUnmappedPath(IncludeSysroot + Path, Group, isFramework);
125  return;
126  }
127  }
128 
129  AddUnmappedPath(Path, Group, isFramework);
130 }
131 
132 void InitHeaderSearch::AddUnmappedPath(const Twine &Path, IncludeDirGroup Group,
133  bool isFramework) {
134  assert(!Path.isTriviallyEmpty() && "can't handle empty path here");
135 
136  FileManager &FM = Headers.getFileMgr();
137  SmallString<256> MappedPathStorage;
138  StringRef MappedPathStr = Path.toStringRef(MappedPathStorage);
139 
140  // Compute the DirectoryLookup type.
142  if (Group == Quoted || Group == Angled || Group == IndexHeaderMap) {
143  Type = SrcMgr::C_User;
144  } else if (Group == ExternCSystem) {
146  } else {
147  Type = SrcMgr::C_System;
148  }
149 
150  // If the directory exists, add it.
151  if (const DirectoryEntry *DE = FM.getDirectory(MappedPathStr)) {
152  IncludePath.push_back(
153  std::make_pair(Group, DirectoryLookup(DE, Type, isFramework)));
154  return;
155  }
156 
157  // Check to see if this is an apple-style headermap (which are not allowed to
158  // be frameworks).
159  if (!isFramework) {
160  if (const FileEntry *FE = FM.getFile(MappedPathStr)) {
161  if (const HeaderMap *HM = Headers.CreateHeaderMap(FE)) {
162  // It is a headermap, add it to the search path.
163  IncludePath.push_back(
164  std::make_pair(Group,
165  DirectoryLookup(HM, Type, Group == IndexHeaderMap)));
166  return;
167  }
168  }
169  }
170 
171  if (Verbose)
172  llvm::errs() << "ignoring nonexistent directory \""
173  << MappedPathStr << "\"\n";
174 }
175 
176 void InitHeaderSearch::AddGnuCPlusPlusIncludePaths(StringRef Base,
177  StringRef ArchDir,
178  StringRef Dir32,
179  StringRef Dir64,
180  const llvm::Triple &triple) {
181  // Add the base dir
182  AddPath(Base, CXXSystem, false);
183 
184  // Add the multilib dirs
185  llvm::Triple::ArchType arch = triple.getArch();
186  bool is64bit = arch == llvm::Triple::ppc64 || arch == llvm::Triple::x86_64;
187  if (is64bit)
188  AddPath(Base + "/" + ArchDir + "/" + Dir64, CXXSystem, false);
189  else
190  AddPath(Base + "/" + ArchDir + "/" + Dir32, CXXSystem, false);
191 
192  // Add the backward dir
193  AddPath(Base + "/backward", CXXSystem, false);
194 }
195 
196 void InitHeaderSearch::AddMinGWCPlusPlusIncludePaths(StringRef Base,
197  StringRef Arch,
198  StringRef Version) {
199  AddPath(Base + "/" + Arch + "/" + Version + "/include/c++",
200  CXXSystem, false);
201  AddPath(Base + "/" + Arch + "/" + Version + "/include/c++/" + Arch,
202  CXXSystem, false);
203  AddPath(Base + "/" + Arch + "/" + Version + "/include/c++/backward",
204  CXXSystem, false);
205 }
206 
207 void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple,
208  const HeaderSearchOptions &HSOpts) {
209  llvm::Triple::OSType os = triple.getOS();
210 
211  if (HSOpts.UseStandardSystemIncludes) {
212  switch (os) {
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:
221  break;
222  case llvm::Triple::Win32:
223  if (triple.getEnvironment() != llvm::Triple::Cygnus)
224  break;
225  default:
226  // FIXME: temporary hack: hard-coded paths.
227  AddPath("/usr/local/include", System, false);
228  break;
229  }
230  }
231 
232  // Builtin includes use #include_next directives and should be positioned
233  // just prior C include dirs.
234  if (HSOpts.UseBuiltinIncludes) {
235  // Ignore the sys root, we *always* look for clang headers relative to
236  // supplied path.
237  SmallString<128> P = StringRef(HSOpts.ResourceDir);
238  llvm::sys::path::append(P, "include");
239  AddUnmappedPath(P, ExternCSystem, false);
240  }
241 
242  // All remaining additions are for system include directories, early exit if
243  // we aren't using them.
244  if (!HSOpts.UseStandardSystemIncludes)
245  return;
246 
247  // Add dirs specified via 'configure --with-c-include-dirs'.
248  StringRef CIncludeDirs(C_INCLUDE_DIRS);
249  if (CIncludeDirs != "") {
251  CIncludeDirs.split(dirs, ":");
252  for (StringRef dir : dirs)
253  AddPath(dir, ExternCSystem, false);
254  return;
255  }
256 
257  switch (os) {
258  case llvm::Triple::Linux:
259  llvm_unreachable("Include management is handled in the driver.");
260 
261  case llvm::Triple::CloudABI: {
262  // <sysroot>/<triple>/include
263  SmallString<128> P = StringRef(HSOpts.ResourceDir);
264  llvm::sys::path::append(P, "../../..", triple.str(), "include");
265  AddPath(P, System, false);
266  break;
267  }
268 
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);
303  break;
304  case llvm::Triple::RTEMS:
305  break;
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);
311  break;
312  case llvm::Triple::GNU:
313  break;
314  }
315  break;
316  default:
317  break;
318  }
319 
320  switch (os) {
321  case llvm::Triple::CloudABI:
322  case llvm::Triple::RTEMS:
323  case llvm::Triple::NaCl:
324  case llvm::Triple::ELFIAMCU:
325  break;
326  case llvm::Triple::PS4: {
327  // <isysroot> gets prepended later in AddPath().
328  std::string BaseSDKPath = "";
329  if (!HasSysroot) {
330  const char *envValue = getenv("SCE_ORBIS_SDK_DIR");
331  if (envValue)
332  BaseSDKPath = envValue;
333  else {
334  // HSOpts.ResourceDir variable contains the location of Clang's
335  // resource files.
336  // Assuming that Clang is configured for PS4 without
337  // --with-clang-resource-dir option, the location of Clang's resource
338  // files is <SDK_DIR>/host_tools/lib/clang
339  SmallString<128> P = StringRef(HSOpts.ResourceDir);
340  llvm::sys::path::append(P, "../../..");
341  BaseSDKPath = P.str();
342  }
343  }
344  AddPath(BaseSDKPath + "/target/include", System, false);
345  if (triple.isPS4CPU())
346  AddPath(BaseSDKPath + "/target/include_common", System, false);
347  }
348  default:
349  AddPath("/usr/include", ExternCSystem, false);
350  break;
351  }
352 }
353 
354 void InitHeaderSearch::
355 AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple, const HeaderSearchOptions &HSOpts) {
356  llvm::Triple::OSType os = triple.getOS();
357  // FIXME: temporary hack: hard-coded paths.
358 
359  if (triple.isOSDarwin()) {
360  switch (triple.getArch()) {
361  default: break;
362 
363  case llvm::Triple::ppc:
364  case llvm::Triple::ppc64:
365  AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1",
366  "powerpc-apple-darwin10", "", "ppc64",
367  triple);
368  AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.0.0",
369  "powerpc-apple-darwin10", "", "ppc64",
370  triple);
371  break;
372 
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);
379  break;
380 
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);
387  break;
388 
389  case llvm::Triple::aarch64:
390  AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1",
391  "arm64-apple-darwin10", "", "", triple);
392  break;
393  }
394  return;
395  }
396 
397  switch (os) {
398  case llvm::Triple::Linux:
399  llvm_unreachable("Include management is handled in the driver.");
400  break;
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:
405  // Cygwin-1.7
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");
409  // g++-4 / Cygwin-1.5
410  AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.3.2");
411  break;
412  }
413  break;
414  case llvm::Triple::DragonFly:
415  AddPath("/usr/include/c++/5.0", CXXSystem, false);
416  break;
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++",
422  t, "", "", triple);
423  break;
424  }
425  case llvm::Triple::Minix:
426  AddGnuCPlusPlusIncludePaths("/usr/gnu/include/c++/4.4.3",
427  "", "", "", triple);
428  break;
429  default:
430  break;
431  }
432 }
433 
434 void InitHeaderSearch::AddDefaultIncludePaths(const LangOptions &Lang,
435  const llvm::Triple &triple,
436  const HeaderSearchOptions &HSOpts) {
437  // NB: This code path is going away. All of the logic is moving into the
438  // driver which has the information necessary to do target-specific
439  // selections of default include paths. Each target which moves there will be
440  // exempted from this logic here until we can delete the entire pile of code.
441  switch (triple.getOS()) {
442  default:
443  break; // Everything else continues to use this routine's logic.
444 
445  case llvm::Triple::Linux:
446  return;
447 
448  case llvm::Triple::Win32:
449  if (triple.getEnvironment() != llvm::Triple::Cygnus ||
450  triple.isOSBinFormatMachO())
451  return;
452  break;
453  }
454 
455  if (Lang.CPlusPlus && HSOpts.UseStandardCXXIncludes &&
456  HSOpts.UseStandardSystemIncludes) {
457  if (HSOpts.UseLibcxx) {
458  if (triple.isOSDarwin()) {
459  // On Darwin, libc++ may be installed alongside the compiler in
460  // include/c++/v1.
461  if (!HSOpts.ResourceDir.empty()) {
462  // Remove version from foo/lib/clang/version
463  StringRef NoVer = llvm::sys::path::parent_path(HSOpts.ResourceDir);
464  // Remove clang from foo/lib/clang
465  StringRef Lib = llvm::sys::path::parent_path(NoVer);
466  // Remove lib from foo/lib
467  SmallString<128> P = llvm::sys::path::parent_path(Lib);
468 
469  // Get foo/include/c++/v1
470  llvm::sys::path::append(P, "include", "c++", "v1");
471  AddUnmappedPath(P, CXXSystem, false);
472  }
473  }
474  AddPath("/usr/include/c++/v1", CXXSystem, false);
475  } else {
476  AddDefaultCPlusPlusIncludePaths(triple, HSOpts);
477  }
478  }
479 
480  AddDefaultCIncludePaths(triple, HSOpts);
481 
482  // Add the default framework include paths on Darwin.
483  if (HSOpts.UseStandardSystemIncludes) {
484  if (triple.isOSDarwin()) {
485  AddPath("/System/Library/Frameworks", System, true);
486  AddPath("/Library/Frameworks", System, true);
487  }
488  }
489 }
490 
491 /// RemoveDuplicates - If there are duplicate directory entries in the specified
492 /// search list, remove the later (dead) ones. Returns the number of non-system
493 /// headers removed, which is used to update NumAngled.
494 static unsigned RemoveDuplicates(std::vector<DirectoryLookup> &SearchList,
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;
502 
503  const DirectoryLookup &CurEntry = SearchList[i];
504 
505  if (CurEntry.isNormalDir()) {
506  // If this isn't the first time we've seen this dir, remove it.
507  if (SeenDirs.insert(CurEntry.getDir()).second)
508  continue;
509  } else if (CurEntry.isFramework()) {
510  // If this isn't the first time we've seen this framework dir, remove it.
511  if (SeenFrameworkDirs.insert(CurEntry.getFrameworkDir()).second)
512  continue;
513  } else {
514  assert(CurEntry.isHeaderMap() && "Not a headermap or normal dir?");
515  // If this isn't the first time we've seen this headermap, remove it.
516  if (SeenHeaderMaps.insert(CurEntry.getHeaderMap()).second)
517  continue;
518  }
519 
520  // If we have a normal #include dir/framework/headermap that is shadowed
521  // later in the chain by a system include location, we actually want to
522  // ignore the user's request and drop the user dir... keeping the system
523  // dir. This is weird, but required to emulate GCC's search path correctly.
524  //
525  // Since dupes of system dirs are rare, just rescan to find the original
526  // that we're nuking instead of using a DenseMap.
527  if (CurEntry.getDirCharacteristic() != SrcMgr::C_User) {
528  // Find the dir that this is the same of.
529  unsigned FirstDir;
530  for (FirstDir = 0; ; ++FirstDir) {
531  assert(FirstDir != i && "Didn't find dupe?");
532 
533  const DirectoryLookup &SearchEntry = SearchList[FirstDir];
534 
535  // If these are different lookup types, then they can't be the dupe.
536  if (SearchEntry.getLookupType() != CurEntry.getLookupType())
537  continue;
538 
539  bool isSame;
540  if (CurEntry.isNormalDir())
541  isSame = SearchEntry.getDir() == CurEntry.getDir();
542  else if (CurEntry.isFramework())
543  isSame = SearchEntry.getFrameworkDir() == CurEntry.getFrameworkDir();
544  else {
545  assert(CurEntry.isHeaderMap() && "Not a headermap or normal dir?");
546  isSame = SearchEntry.getHeaderMap() == CurEntry.getHeaderMap();
547  }
548 
549  if (isSame)
550  break;
551  }
552 
553  // If the first dir in the search path is a non-system dir, zap it
554  // instead of the system one.
555  if (SearchList[FirstDir].getDirCharacteristic() == SrcMgr::C_User)
556  DirToRemove = FirstDir;
557  }
558 
559  if (Verbose) {
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";
565  }
566  if (DirToRemove != i)
567  ++NonSystemRemoved;
568 
569  // This is reached if the current entry is a duplicate. Remove the
570  // DirToRemove (usually the current dir).
571  SearchList.erase(SearchList.begin()+DirToRemove);
572  --i;
573  }
574  return NonSystemRemoved;
575 }
576 
577 
578 void InitHeaderSearch::Realize(const LangOptions &Lang) {
579  // Concatenate ANGLE+SYSTEM+AFTER chains together into SearchList.
580  std::vector<DirectoryLookup> SearchList;
581  SearchList.reserve(IncludePath.size());
582 
583  // Quoted arguments go first.
584  for (auto &Include : IncludePath)
585  if (Include.first == Quoted)
586  SearchList.push_back(Include.second);
587 
588  // Deduplicate and remember index.
589  RemoveDuplicates(SearchList, 0, Verbose);
590  unsigned NumQuoted = SearchList.size();
591 
592  for (auto &Include : IncludePath)
593  if (Include.first == Angled || Include.first == IndexHeaderMap)
594  SearchList.push_back(Include.second);
595 
596  RemoveDuplicates(SearchList, NumQuoted, Verbose);
597  unsigned NumAngled = SearchList.size();
598 
599  for (auto &Include : IncludePath)
600  if (Include.first == System || Include.first == ExternCSystem ||
601  (!Lang.ObjC1 && !Lang.CPlusPlus && Include.first == CSystem) ||
602  (/*FIXME !Lang.ObjC1 && */ Lang.CPlusPlus &&
603  Include.first == CXXSystem) ||
604  (Lang.ObjC1 && !Lang.CPlusPlus && Include.first == ObjCSystem) ||
605  (Lang.ObjC1 && Lang.CPlusPlus && Include.first == ObjCXXSystem))
606  SearchList.push_back(Include.second);
607 
608  for (auto &Include : IncludePath)
609  if (Include.first == After)
610  SearchList.push_back(Include.second);
611 
612  // Remove duplicates across both the Angled and System directories. GCC does
613  // this and failing to remove duplicates across these two groups breaks
614  // #include_next.
615  unsigned NonSystemRemoved = RemoveDuplicates(SearchList, NumQuoted, Verbose);
616  NumAngled -= NonSystemRemoved;
617 
618  bool DontSearchCurDir = false; // TODO: set to true if -I- is set?
619  Headers.SetSearchPaths(SearchList, NumQuoted, NumAngled, DontSearchCurDir);
620 
621  Headers.SetSystemHeaderPrefixes(SystemHeaderPrefixes);
622 
623  // If verbose, print the list of directories that will be searched.
624  if (Verbose) {
625  llvm::errs() << "#include \"...\" search starts here:\n";
626  for (unsigned i = 0, e = SearchList.size(); i != e; ++i) {
627  if (i == NumQuoted)
628  llvm::errs() << "#include <...> search starts here:\n";
629  const char *Name = SearchList[i].getName();
630  const char *Suffix;
631  if (SearchList[i].isNormalDir())
632  Suffix = "";
633  else if (SearchList[i].isFramework())
634  Suffix = " (framework directory)";
635  else {
636  assert(SearchList[i].isHeaderMap() && "Unknown DirectoryLookup");
637  Suffix = " (headermap)";
638  }
639  llvm::errs() << " " << Name << Suffix << "\n";
640  }
641  llvm::errs() << "End of search list.\n";
642  }
643 }
644 
646  const HeaderSearchOptions &HSOpts,
647  const LangOptions &Lang,
648  const llvm::Triple &Triple) {
649  InitHeaderSearch Init(HS, HSOpts.Verbose, HSOpts.Sysroot);
650 
651  // Add the user defined entries.
652  for (unsigned i = 0, e = HSOpts.UserEntries.size(); i != e; ++i) {
653  const HeaderSearchOptions::Entry &E = HSOpts.UserEntries[i];
654  if (E.IgnoreSysRoot) {
655  Init.AddUnmappedPath(E.Path, E.Group, E.IsFramework);
656  } else {
657  Init.AddPath(E.Path, E.Group, E.IsFramework);
658  }
659  }
660 
661  Init.AddDefaultIncludePaths(Lang, Triple, HSOpts);
662 
663  for (unsigned i = 0, e = HSOpts.SystemHeaderPrefixes.size(); i != e; ++i)
664  Init.AddSystemHeaderPrefix(HSOpts.SystemHeaderPrefixes[i].Prefix,
665  HSOpts.SystemHeaderPrefixes[i].IsSystemHeader);
666 
667  if (HSOpts.UseBuiltinIncludes) {
668  // Set up the builtin include directory in the module map.
669  SmallString<128> P = StringRef(HSOpts.ResourceDir);
670  llvm::sys::path::append(P, "include");
671  if (const DirectoryEntry *Dir = HS.getFileMgr().getDirectory(P))
673  }
674 
675  Init.Realize(Lang);
676 }
Paths for '#include <>' added by '-I'.
unsigned UseLibcxx
Use libc++ instead of the default libstdc++.
Implements support for file system lookup, file system caching, and directory search management...
Definition: FileManager.h:117
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++.
StringRef P
The base class of the type hierarchy.
Definition: Type.h:1281
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...
Definition: SourceManager.h:78
ModuleMap & getModuleMap()
Retrieve the module map.
Definition: HeaderSearch.h:590
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. ...
Definition: Type.h:4549
This class represents an Apple concept known as a 'header map'.
Definition: HeaderMap.h:67
bool isFramework() const
isFramework - True if this is a framework directory.
std::vector< Entry > UserEntries
User specified include entries.
std::vector< SystemHeaderPrefix > SystemHeaderPrefixes
User-specified system header prefixes.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:48
std::string ResourceDir
The directory which holds the compiler resource files (builtin includes, etc.).
Encapsulates the information needed to find the file referenced by a #include or #include_next, (sub-)framework lookup, etc.
Definition: HeaderSearch.h:137
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.
unsigned IgnoreSysRoot
IgnoreSysRoot - This is false if an absolute path should be treated relative to the sysroot...
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...
unsigned UseBuiltinIncludes
Include the compiler builtin includes.
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...
Definition: ModuleMap.h:304
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.
unsigned UseStandardSystemIncludes
Include the system standard include search directories.
Cached information about one file (either on disk or in the virtual file system). ...
Definition: FileManager.h:53
FileManager & getFileMgr() const
Definition: HeaderSearch.h:260
unsigned Verbose
Whether header search information should be output as for -v.
frontend::IncludeDirGroup Group
Like System, but only used for ObjC.
'#include ""' paths, added by 'gcc -iquote'.
building frameworks.
Like System, but only used for C.
detail::InMemoryDirectory::const_iterator E
static unsigned RemoveDuplicates(std::vector< DirectoryLookup > &SearchList, unsigned First, bool Verbose)
RemoveDuplicates - If there are duplicate directory entries in the specified search list...
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).
Definition: FileManager.h:40
bool isHeaderMap() const
isHeaderMap - Return true if this is a header map, not a normal directory.
HeaderSearchOptions - Helper class for storing options related to the initialization of the HeaderSea...
Like Angled, but marks header maps used when.
std::string Sysroot
If non-empty, the directory to use as a "virtual system root" for include paths.
static bool CanPrefixSysroot(StringRef Path)
const DirectoryEntry * getDir() const
getDir - Return the directory that this entry refers to.
unsigned UseStandardCXXIncludes
Include the system standard C++ library include search directories.