clang  5.0.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 
16 #include "clang/Config/config.h" // C_INCLUDE_DIRS
17 #include "clang/Frontend/Utils.h"
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/Path.h"
29 #include "llvm/Support/raw_ostream.h"
30 
31 using namespace clang;
32 using namespace clang::frontend;
33 
34 namespace {
35 
36 /// InitHeaderSearch - This class makes it easier to set the search paths of
37 /// a HeaderSearch object. InitHeaderSearch stores several search path lists
38 /// internally, which can be sent to a HeaderSearch object in one swoop.
39 class InitHeaderSearch {
40  std::vector<std::pair<IncludeDirGroup, DirectoryLookup> > IncludePath;
41  typedef std::vector<std::pair<IncludeDirGroup,
42  DirectoryLookup> >::const_iterator path_iterator;
43  std::vector<std::pair<std::string, bool> > SystemHeaderPrefixes;
44  HeaderSearch &Headers;
45  bool Verbose;
46  std::string IncludeSysroot;
47  bool HasSysroot;
48 
49 public:
50 
51  InitHeaderSearch(HeaderSearch &HS, bool verbose, StringRef sysroot)
52  : Headers(HS), Verbose(verbose), IncludeSysroot(sysroot),
53  HasSysroot(!(sysroot.empty() || sysroot == "/")) {
54  }
55 
56  /// AddPath - Add the specified path to the specified group list, prefixing
57  /// the sysroot if used.
58  void AddPath(const Twine &Path, IncludeDirGroup Group, bool isFramework);
59 
60  /// AddUnmappedPath - Add the specified path to the specified group list,
61  /// without performing any sysroot remapping.
62  void AddUnmappedPath(const Twine &Path, IncludeDirGroup Group,
63  bool isFramework);
64 
65  /// AddSystemHeaderPrefix - Add the specified prefix to the system header
66  /// prefix list.
67  void AddSystemHeaderPrefix(StringRef Prefix, bool IsSystemHeader) {
68  SystemHeaderPrefixes.emplace_back(Prefix, IsSystemHeader);
69  }
70 
71  /// AddGnuCPlusPlusIncludePaths - Add the necessary paths to support a gnu
72  /// libstdc++.
73  void AddGnuCPlusPlusIncludePaths(StringRef Base,
74  StringRef ArchDir,
75  StringRef Dir32,
76  StringRef Dir64,
77  const llvm::Triple &triple);
78 
79  /// AddMinGWCPlusPlusIncludePaths - Add the necessary paths to support a MinGW
80  /// libstdc++.
81  void AddMinGWCPlusPlusIncludePaths(StringRef Base,
82  StringRef Arch,
83  StringRef Version);
84 
85  // AddDefaultCIncludePaths - Add paths that should always be searched.
86  void AddDefaultCIncludePaths(const llvm::Triple &triple,
87  const HeaderSearchOptions &HSOpts);
88 
89  // AddDefaultCPlusPlusIncludePaths - Add paths that should be searched when
90  // compiling c++.
91  void AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple,
92  const HeaderSearchOptions &HSOpts);
93 
94  /// AddDefaultSystemIncludePaths - Adds the default system include paths so
95  /// that e.g. stdio.h is found.
96  void AddDefaultIncludePaths(const LangOptions &Lang,
97  const llvm::Triple &triple,
98  const HeaderSearchOptions &HSOpts);
99 
100  /// Realize - Merges all search path lists into one list and send it to
101  /// HeaderSearch.
102  void Realize(const LangOptions &Lang);
103 };
104 
105 } // end anonymous namespace.
106 
107 static bool CanPrefixSysroot(StringRef Path) {
108 #if defined(LLVM_ON_WIN32)
109  return !Path.empty() && llvm::sys::path::is_separator(Path[0]);
110 #else
111  return llvm::sys::path::is_absolute(Path);
112 #endif
113 }
114 
115 void InitHeaderSearch::AddPath(const Twine &Path, IncludeDirGroup Group,
116  bool isFramework) {
117  // Add the path with sysroot prepended, if desired and this is a system header
118  // group.
119  if (HasSysroot) {
120  SmallString<256> MappedPathStorage;
121  StringRef MappedPathStr = Path.toStringRef(MappedPathStorage);
122  if (CanPrefixSysroot(MappedPathStr)) {
123  AddUnmappedPath(IncludeSysroot + Path, Group, isFramework);
124  return;
125  }
126  }
127 
128  AddUnmappedPath(Path, Group, isFramework);
129 }
130 
131 void InitHeaderSearch::AddUnmappedPath(const Twine &Path, IncludeDirGroup Group,
132  bool isFramework) {
133  assert(!Path.isTriviallyEmpty() && "can't handle empty path here");
134 
135  FileManager &FM = Headers.getFileMgr();
136  SmallString<256> MappedPathStorage;
137  StringRef MappedPathStr = Path.toStringRef(MappedPathStorage);
138 
139  // Compute the DirectoryLookup type.
141  if (Group == Quoted || Group == Angled || Group == IndexHeaderMap) {
142  Type = SrcMgr::C_User;
143  } else if (Group == ExternCSystem) {
145  } else {
146  Type = SrcMgr::C_System;
147  }
148 
149  // If the directory exists, add it.
150  if (const DirectoryEntry *DE = FM.getDirectory(MappedPathStr)) {
151  IncludePath.push_back(
152  std::make_pair(Group, DirectoryLookup(DE, Type, isFramework)));
153  return;
154  }
155 
156  // Check to see if this is an apple-style headermap (which are not allowed to
157  // be frameworks).
158  if (!isFramework) {
159  if (const FileEntry *FE = FM.getFile(MappedPathStr)) {
160  if (const HeaderMap *HM = Headers.CreateHeaderMap(FE)) {
161  // It is a headermap, add it to the search path.
162  IncludePath.push_back(
163  std::make_pair(Group,
164  DirectoryLookup(HM, Type, Group == IndexHeaderMap)));
165  return;
166  }
167  }
168  }
169 
170  if (Verbose)
171  llvm::errs() << "ignoring nonexistent directory \""
172  << MappedPathStr << "\"\n";
173 }
174 
175 void InitHeaderSearch::AddGnuCPlusPlusIncludePaths(StringRef Base,
176  StringRef ArchDir,
177  StringRef Dir32,
178  StringRef Dir64,
179  const llvm::Triple &triple) {
180  // Add the base dir
181  AddPath(Base, CXXSystem, false);
182 
183  // Add the multilib dirs
184  llvm::Triple::ArchType arch = triple.getArch();
185  bool is64bit = arch == llvm::Triple::ppc64 || arch == llvm::Triple::x86_64;
186  if (is64bit)
187  AddPath(Base + "/" + ArchDir + "/" + Dir64, CXXSystem, false);
188  else
189  AddPath(Base + "/" + ArchDir + "/" + Dir32, CXXSystem, false);
190 
191  // Add the backward dir
192  AddPath(Base + "/backward", CXXSystem, false);
193 }
194 
195 void InitHeaderSearch::AddMinGWCPlusPlusIncludePaths(StringRef Base,
196  StringRef Arch,
197  StringRef Version) {
198  AddPath(Base + "/" + Arch + "/" + Version + "/include/c++",
199  CXXSystem, false);
200  AddPath(Base + "/" + Arch + "/" + Version + "/include/c++/" + Arch,
201  CXXSystem, false);
202  AddPath(Base + "/" + Arch + "/" + Version + "/include/c++/backward",
203  CXXSystem, false);
204 }
205 
206 void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple,
207  const HeaderSearchOptions &HSOpts) {
208  llvm::Triple::OSType os = triple.getOS();
209 
210  if (HSOpts.UseStandardSystemIncludes) {
211  switch (os) {
212  case llvm::Triple::CloudABI:
213  case llvm::Triple::FreeBSD:
214  case llvm::Triple::NetBSD:
215  case llvm::Triple::OpenBSD:
216  case llvm::Triple::Bitrig:
217  case llvm::Triple::NaCl:
218  case llvm::Triple::PS4:
219  case llvm::Triple::ELFIAMCU:
220  break;
221  case llvm::Triple::Win32:
222  if (triple.getEnvironment() != llvm::Triple::Cygnus)
223  break;
224  LLVM_FALLTHROUGH;
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  LLVM_FALLTHROUGH;
348  }
349  default:
350  AddPath("/usr/include", ExternCSystem, false);
351  break;
352  }
353 }
354 
355 void InitHeaderSearch::
356 AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple, const HeaderSearchOptions &HSOpts) {
357  llvm::Triple::OSType os = triple.getOS();
358  // FIXME: temporary hack: hard-coded paths.
359 
360  if (triple.isOSDarwin()) {
361  switch (triple.getArch()) {
362  default: break;
363 
364  case llvm::Triple::ppc:
365  case llvm::Triple::ppc64:
366  AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1",
367  "powerpc-apple-darwin10", "", "ppc64",
368  triple);
369  AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.0.0",
370  "powerpc-apple-darwin10", "", "ppc64",
371  triple);
372  break;
373 
374  case llvm::Triple::x86:
375  case llvm::Triple::x86_64:
376  AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1",
377  "i686-apple-darwin10", "", "x86_64", triple);
378  AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.0.0",
379  "i686-apple-darwin8", "", "", triple);
380  break;
381 
382  case llvm::Triple::arm:
383  case llvm::Triple::thumb:
384  AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1",
385  "arm-apple-darwin10", "v7", "", triple);
386  AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1",
387  "arm-apple-darwin10", "v6", "", triple);
388  break;
389 
390  case llvm::Triple::aarch64:
391  AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1",
392  "arm64-apple-darwin10", "", "", triple);
393  break;
394  }
395  return;
396  }
397 
398  switch (os) {
399  case llvm::Triple::Linux:
400  llvm_unreachable("Include management is handled in the driver.");
401  break;
402  case llvm::Triple::Win32:
403  switch (triple.getEnvironment()) {
404  default: llvm_unreachable("Include management is handled in the driver.");
405  case llvm::Triple::Cygnus:
406  // Cygwin-1.7
407  AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.7.3");
408  AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.5.3");
409  AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.3.4");
410  // g++-4 / Cygwin-1.5
411  AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.3.2");
412  break;
413  }
414  break;
415  case llvm::Triple::DragonFly:
416  AddPath("/usr/include/c++/5.0", CXXSystem, false);
417  break;
418  case llvm::Triple::OpenBSD: {
419  std::string t = triple.getTriple();
420  if (t.substr(0, 6) == "x86_64")
421  t.replace(0, 6, "amd64");
422  AddGnuCPlusPlusIncludePaths("/usr/include/g++",
423  t, "", "", triple);
424  break;
425  }
426  case llvm::Triple::Minix:
427  AddGnuCPlusPlusIncludePaths("/usr/gnu/include/c++/4.4.3",
428  "", "", "", triple);
429  break;
430  default:
431  break;
432  }
433 }
434 
435 void InitHeaderSearch::AddDefaultIncludePaths(const LangOptions &Lang,
436  const llvm::Triple &triple,
437  const HeaderSearchOptions &HSOpts) {
438  // NB: This code path is going away. All of the logic is moving into the
439  // driver which has the information necessary to do target-specific
440  // selections of default include paths. Each target which moves there will be
441  // exempted from this logic here until we can delete the entire pile of code.
442  switch (triple.getOS()) {
443  default:
444  break; // Everything else continues to use this routine's logic.
445 
446  case llvm::Triple::Linux:
447  return;
448 
449  case llvm::Triple::Win32:
450  if (triple.getEnvironment() != llvm::Triple::Cygnus ||
451  triple.isOSBinFormatMachO())
452  return;
453  break;
454  }
455 
456  if (Lang.CPlusPlus && HSOpts.UseStandardCXXIncludes &&
457  HSOpts.UseStandardSystemIncludes) {
458  if (HSOpts.UseLibcxx) {
459  if (triple.isOSDarwin()) {
460  // On Darwin, libc++ may be installed alongside the compiler in
461  // include/c++/v1.
462  if (!HSOpts.ResourceDir.empty()) {
463  // Remove version from foo/lib/clang/version
464  StringRef NoVer = llvm::sys::path::parent_path(HSOpts.ResourceDir);
465  // Remove clang from foo/lib/clang
466  StringRef Lib = llvm::sys::path::parent_path(NoVer);
467  // Remove lib from foo/lib
468  SmallString<128> P = llvm::sys::path::parent_path(Lib);
469 
470  // Get foo/include/c++/v1
471  llvm::sys::path::append(P, "include", "c++", "v1");
472  AddUnmappedPath(P, CXXSystem, false);
473  }
474  }
475  AddPath("/usr/include/c++/v1", CXXSystem, false);
476  } else {
477  AddDefaultCPlusPlusIncludePaths(triple, HSOpts);
478  }
479  }
480 
481  AddDefaultCIncludePaths(triple, HSOpts);
482 
483  // Add the default framework include paths on Darwin.
484  if (HSOpts.UseStandardSystemIncludes) {
485  if (triple.isOSDarwin()) {
486  AddPath("/System/Library/Frameworks", System, true);
487  AddPath("/Library/Frameworks", System, true);
488  }
489  }
490 }
491 
492 /// RemoveDuplicates - If there are duplicate directory entries in the specified
493 /// search list, remove the later (dead) ones. Returns the number of non-system
494 /// headers removed, which is used to update NumAngled.
495 static unsigned RemoveDuplicates(std::vector<DirectoryLookup> &SearchList,
496  unsigned First, bool Verbose) {
497  llvm::SmallPtrSet<const DirectoryEntry *, 8> SeenDirs;
498  llvm::SmallPtrSet<const DirectoryEntry *, 8> SeenFrameworkDirs;
499  llvm::SmallPtrSet<const HeaderMap *, 8> SeenHeaderMaps;
500  unsigned NonSystemRemoved = 0;
501  for (unsigned i = First; i != SearchList.size(); ++i) {
502  unsigned DirToRemove = i;
503 
504  const DirectoryLookup &CurEntry = SearchList[i];
505 
506  if (CurEntry.isNormalDir()) {
507  // If this isn't the first time we've seen this dir, remove it.
508  if (SeenDirs.insert(CurEntry.getDir()).second)
509  continue;
510  } else if (CurEntry.isFramework()) {
511  // If this isn't the first time we've seen this framework dir, remove it.
512  if (SeenFrameworkDirs.insert(CurEntry.getFrameworkDir()).second)
513  continue;
514  } else {
515  assert(CurEntry.isHeaderMap() && "Not a headermap or normal dir?");
516  // If this isn't the first time we've seen this headermap, remove it.
517  if (SeenHeaderMaps.insert(CurEntry.getHeaderMap()).second)
518  continue;
519  }
520 
521  // If we have a normal #include dir/framework/headermap that is shadowed
522  // later in the chain by a system include location, we actually want to
523  // ignore the user's request and drop the user dir... keeping the system
524  // dir. This is weird, but required to emulate GCC's search path correctly.
525  //
526  // Since dupes of system dirs are rare, just rescan to find the original
527  // that we're nuking instead of using a DenseMap.
528  if (CurEntry.getDirCharacteristic() != SrcMgr::C_User) {
529  // Find the dir that this is the same of.
530  unsigned FirstDir;
531  for (FirstDir = First;; ++FirstDir) {
532  assert(FirstDir != i && "Didn't find dupe?");
533 
534  const DirectoryLookup &SearchEntry = SearchList[FirstDir];
535 
536  // If these are different lookup types, then they can't be the dupe.
537  if (SearchEntry.getLookupType() != CurEntry.getLookupType())
538  continue;
539 
540  bool isSame;
541  if (CurEntry.isNormalDir())
542  isSame = SearchEntry.getDir() == CurEntry.getDir();
543  else if (CurEntry.isFramework())
544  isSame = SearchEntry.getFrameworkDir() == CurEntry.getFrameworkDir();
545  else {
546  assert(CurEntry.isHeaderMap() && "Not a headermap or normal dir?");
547  isSame = SearchEntry.getHeaderMap() == CurEntry.getHeaderMap();
548  }
549 
550  if (isSame)
551  break;
552  }
553 
554  // If the first dir in the search path is a non-system dir, zap it
555  // instead of the system one.
556  if (SearchList[FirstDir].getDirCharacteristic() == SrcMgr::C_User)
557  DirToRemove = FirstDir;
558  }
559 
560  if (Verbose) {
561  llvm::errs() << "ignoring duplicate directory \""
562  << CurEntry.getName() << "\"\n";
563  if (DirToRemove != i)
564  llvm::errs() << " as it is a non-system directory that duplicates "
565  << "a system directory\n";
566  }
567  if (DirToRemove != i)
568  ++NonSystemRemoved;
569 
570  // This is reached if the current entry is a duplicate. Remove the
571  // DirToRemove (usually the current dir).
572  SearchList.erase(SearchList.begin()+DirToRemove);
573  --i;
574  }
575  return NonSystemRemoved;
576 }
577 
578 
579 void InitHeaderSearch::Realize(const LangOptions &Lang) {
580  // Concatenate ANGLE+SYSTEM+AFTER chains together into SearchList.
581  std::vector<DirectoryLookup> SearchList;
582  SearchList.reserve(IncludePath.size());
583 
584  // Quoted arguments go first.
585  for (auto &Include : IncludePath)
586  if (Include.first == Quoted)
587  SearchList.push_back(Include.second);
588 
589  // Deduplicate and remember index.
590  RemoveDuplicates(SearchList, 0, Verbose);
591  unsigned NumQuoted = SearchList.size();
592 
593  for (auto &Include : IncludePath)
594  if (Include.first == Angled || Include.first == IndexHeaderMap)
595  SearchList.push_back(Include.second);
596 
597  RemoveDuplicates(SearchList, NumQuoted, Verbose);
598  unsigned NumAngled = SearchList.size();
599 
600  for (auto &Include : IncludePath)
601  if (Include.first == System || Include.first == ExternCSystem ||
602  (!Lang.ObjC1 && !Lang.CPlusPlus && Include.first == CSystem) ||
603  (/*FIXME !Lang.ObjC1 && */ Lang.CPlusPlus &&
604  Include.first == CXXSystem) ||
605  (Lang.ObjC1 && !Lang.CPlusPlus && Include.first == ObjCSystem) ||
606  (Lang.ObjC1 && Lang.CPlusPlus && Include.first == ObjCXXSystem))
607  SearchList.push_back(Include.second);
608 
609  for (auto &Include : IncludePath)
610  if (Include.first == After)
611  SearchList.push_back(Include.second);
612 
613  // Remove duplicates across both the Angled and System directories. GCC does
614  // this and failing to remove duplicates across these two groups breaks
615  // #include_next.
616  unsigned NonSystemRemoved = RemoveDuplicates(SearchList, NumQuoted, Verbose);
617  NumAngled -= NonSystemRemoved;
618 
619  bool DontSearchCurDir = false; // TODO: set to true if -I- is set?
620  Headers.SetSearchPaths(SearchList, NumQuoted, NumAngled, DontSearchCurDir);
621 
622  Headers.SetSystemHeaderPrefixes(SystemHeaderPrefixes);
623 
624  // If verbose, print the list of directories that will be searched.
625  if (Verbose) {
626  llvm::errs() << "#include \"...\" search starts here:\n";
627  for (unsigned i = 0, e = SearchList.size(); i != e; ++i) {
628  if (i == NumQuoted)
629  llvm::errs() << "#include <...> search starts here:\n";
630  StringRef Name = SearchList[i].getName();
631  const char *Suffix;
632  if (SearchList[i].isNormalDir())
633  Suffix = "";
634  else if (SearchList[i].isFramework())
635  Suffix = " (framework directory)";
636  else {
637  assert(SearchList[i].isHeaderMap() && "Unknown DirectoryLookup");
638  Suffix = " (headermap)";
639  }
640  llvm::errs() << " " << Name << Suffix << "\n";
641  }
642  llvm::errs() << "End of search list.\n";
643  }
644 }
645 
647  const HeaderSearchOptions &HSOpts,
648  const LangOptions &Lang,
649  const llvm::Triple &Triple) {
650  InitHeaderSearch Init(HS, HSOpts.Verbose, HSOpts.Sysroot);
651 
652  // Add the user defined entries.
653  for (unsigned i = 0, e = HSOpts.UserEntries.size(); i != e; ++i) {
654  const HeaderSearchOptions::Entry &E = HSOpts.UserEntries[i];
655  if (E.IgnoreSysRoot) {
656  Init.AddUnmappedPath(E.Path, E.Group, E.IsFramework);
657  } else {
658  Init.AddPath(E.Path, E.Group, E.IsFramework);
659  }
660  }
661 
662  Init.AddDefaultIncludePaths(Lang, Triple, HSOpts);
663 
664  for (unsigned i = 0, e = HSOpts.SystemHeaderPrefixes.size(); i != e; ++i)
665  Init.AddSystemHeaderPrefix(HSOpts.SystemHeaderPrefixes[i].Prefix,
666  HSOpts.SystemHeaderPrefixes[i].IsSystemHeader);
667 
668  if (HSOpts.UseBuiltinIncludes) {
669  // Set up the builtin include directory in the module map.
670  SmallString<128> P = StringRef(HSOpts.ResourceDir);
671  llvm::sys::path::append(P, "include");
672  if (const DirectoryEntry *Dir = HS.getFileMgr().getDirectory(P))
674  }
675 
676  Init.Realize(Lang);
677 }
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:116
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:1303
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...
Definition: SourceManager.h:82
ModuleMap & getModuleMap()
Retrieve the module map.
Definition: HeaderSearch.h:624
Like System, but searched after the system directories.
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.
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:352
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:59
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.
StringRef Name
Definition: USRFinder.cpp:123
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...
Cached information about one directory (either on disk or in the virtual file system).
Definition: FileManager.h:45
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.