InitHeaderSearch.cpp revision 1.1.1.1.4.1 1 1.1 joerg //===--- InitHeaderSearch.cpp - Initialize header search paths ------------===//
2 1.1 joerg //
3 1.1 joerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 1.1 joerg // See https://llvm.org/LICENSE.txt for license information.
5 1.1 joerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 1.1 joerg //
7 1.1 joerg //===----------------------------------------------------------------------===//
8 1.1 joerg //
9 1.1 joerg // This file implements the InitHeaderSearch class.
10 1.1 joerg //
11 1.1 joerg //===----------------------------------------------------------------------===//
12 1.1 joerg
13 1.1 joerg #include "clang/Basic/FileManager.h"
14 1.1 joerg #include "clang/Basic/LangOptions.h"
15 1.1 joerg #include "clang/Config/config.h" // C_INCLUDE_DIRS
16 1.1 joerg #include "clang/Frontend/FrontendDiagnostic.h"
17 1.1 joerg #include "clang/Frontend/Utils.h"
18 1.1 joerg #include "clang/Lex/HeaderMap.h"
19 1.1 joerg #include "clang/Lex/HeaderSearch.h"
20 1.1 joerg #include "clang/Lex/HeaderSearchOptions.h"
21 1.1 joerg #include "llvm/ADT/SmallPtrSet.h"
22 1.1 joerg #include "llvm/ADT/SmallString.h"
23 1.1 joerg #include "llvm/ADT/SmallVector.h"
24 1.1 joerg #include "llvm/ADT/StringExtras.h"
25 1.1 joerg #include "llvm/ADT/Triple.h"
26 1.1 joerg #include "llvm/ADT/Twine.h"
27 1.1 joerg #include "llvm/Support/ErrorHandling.h"
28 1.1 joerg #include "llvm/Support/Path.h"
29 1.1 joerg #include "llvm/Support/raw_ostream.h"
30 1.1 joerg
31 1.1 joerg using namespace clang;
32 1.1 joerg using namespace clang::frontend;
33 1.1 joerg
34 1.1 joerg namespace {
35 1.1 joerg
36 1.1 joerg /// InitHeaderSearch - This class makes it easier to set the search paths of
37 1.1 joerg /// a HeaderSearch object. InitHeaderSearch stores several search path lists
38 1.1 joerg /// internally, which can be sent to a HeaderSearch object in one swoop.
39 1.1 joerg class InitHeaderSearch {
40 1.1 joerg std::vector<std::pair<IncludeDirGroup, DirectoryLookup> > IncludePath;
41 1.1 joerg typedef std::vector<std::pair<IncludeDirGroup,
42 1.1 joerg DirectoryLookup> >::const_iterator path_iterator;
43 1.1 joerg std::vector<std::pair<std::string, bool> > SystemHeaderPrefixes;
44 1.1 joerg HeaderSearch &Headers;
45 1.1 joerg bool Verbose;
46 1.1 joerg std::string IncludeSysroot;
47 1.1 joerg bool HasSysroot;
48 1.1 joerg
49 1.1 joerg public:
50 1.1 joerg InitHeaderSearch(HeaderSearch &HS, bool verbose, StringRef sysroot)
51 1.1.1.1.4.1 cjep : Headers(HS), Verbose(verbose), IncludeSysroot(std::string(sysroot)),
52 1.1.1.1.4.1 cjep HasSysroot(!(sysroot.empty() || sysroot == "/")) {}
53 1.1 joerg
54 1.1 joerg /// AddPath - Add the specified path to the specified group list, prefixing
55 1.1 joerg /// the sysroot if used.
56 1.1 joerg /// Returns true if the path exists, false if it was ignored.
57 1.1 joerg bool AddPath(const Twine &Path, IncludeDirGroup Group, bool isFramework);
58 1.1 joerg
59 1.1 joerg /// AddUnmappedPath - Add the specified path to the specified group list,
60 1.1 joerg /// without performing any sysroot remapping.
61 1.1 joerg /// Returns true if the path exists, false if it was ignored.
62 1.1 joerg bool AddUnmappedPath(const Twine &Path, IncludeDirGroup Group,
63 1.1 joerg bool isFramework);
64 1.1 joerg
65 1.1 joerg /// AddSystemHeaderPrefix - Add the specified prefix to the system header
66 1.1 joerg /// prefix list.
67 1.1 joerg void AddSystemHeaderPrefix(StringRef Prefix, bool IsSystemHeader) {
68 1.1.1.1.4.1 cjep SystemHeaderPrefixes.emplace_back(std::string(Prefix), IsSystemHeader);
69 1.1 joerg }
70 1.1 joerg
71 1.1 joerg /// AddGnuCPlusPlusIncludePaths - Add the necessary paths to support a gnu
72 1.1 joerg /// libstdc++.
73 1.1 joerg /// Returns true if the \p Base path was found, false if it does not exist.
74 1.1 joerg bool AddGnuCPlusPlusIncludePaths(StringRef Base, StringRef ArchDir,
75 1.1 joerg StringRef Dir32, StringRef Dir64,
76 1.1 joerg const llvm::Triple &triple);
77 1.1 joerg
78 1.1 joerg /// AddMinGWCPlusPlusIncludePaths - Add the necessary paths to support a MinGW
79 1.1 joerg /// libstdc++.
80 1.1 joerg void AddMinGWCPlusPlusIncludePaths(StringRef Base,
81 1.1 joerg StringRef Arch,
82 1.1 joerg StringRef Version);
83 1.1 joerg
84 1.1 joerg // AddDefaultCIncludePaths - Add paths that should always be searched.
85 1.1 joerg void AddDefaultCIncludePaths(const llvm::Triple &triple,
86 1.1 joerg const HeaderSearchOptions &HSOpts);
87 1.1 joerg
88 1.1 joerg // AddDefaultCPlusPlusIncludePaths - Add paths that should be searched when
89 1.1 joerg // compiling c++.
90 1.1 joerg void AddDefaultCPlusPlusIncludePaths(const LangOptions &LangOpts,
91 1.1 joerg const llvm::Triple &triple,
92 1.1 joerg const HeaderSearchOptions &HSOpts);
93 1.1 joerg
94 1.1 joerg /// AddDefaultSystemIncludePaths - Adds the default system include paths so
95 1.1 joerg /// that e.g. stdio.h is found.
96 1.1 joerg void AddDefaultIncludePaths(const LangOptions &Lang,
97 1.1 joerg const llvm::Triple &triple,
98 1.1 joerg const HeaderSearchOptions &HSOpts);
99 1.1 joerg
100 1.1 joerg /// Realize - Merges all search path lists into one list and send it to
101 1.1 joerg /// HeaderSearch.
102 1.1 joerg void Realize(const LangOptions &Lang);
103 1.1 joerg };
104 1.1 joerg
105 1.1 joerg } // end anonymous namespace.
106 1.1 joerg
107 1.1 joerg static bool CanPrefixSysroot(StringRef Path) {
108 1.1 joerg #if defined(_WIN32)
109 1.1 joerg return !Path.empty() && llvm::sys::path::is_separator(Path[0]);
110 1.1 joerg #else
111 1.1 joerg return llvm::sys::path::is_absolute(Path);
112 1.1 joerg #endif
113 1.1 joerg }
114 1.1 joerg
115 1.1 joerg bool InitHeaderSearch::AddPath(const Twine &Path, IncludeDirGroup Group,
116 1.1 joerg bool isFramework) {
117 1.1 joerg // Add the path with sysroot prepended, if desired and this is a system header
118 1.1 joerg // group.
119 1.1 joerg if (HasSysroot) {
120 1.1 joerg SmallString<256> MappedPathStorage;
121 1.1 joerg StringRef MappedPathStr = Path.toStringRef(MappedPathStorage);
122 1.1 joerg if (CanPrefixSysroot(MappedPathStr)) {
123 1.1 joerg return AddUnmappedPath(IncludeSysroot + Path, Group, isFramework);
124 1.1 joerg }
125 1.1 joerg }
126 1.1 joerg
127 1.1 joerg return AddUnmappedPath(Path, Group, isFramework);
128 1.1 joerg }
129 1.1 joerg
130 1.1 joerg bool InitHeaderSearch::AddUnmappedPath(const Twine &Path, IncludeDirGroup Group,
131 1.1 joerg bool isFramework) {
132 1.1 joerg assert(!Path.isTriviallyEmpty() && "can't handle empty path here");
133 1.1 joerg
134 1.1 joerg FileManager &FM = Headers.getFileMgr();
135 1.1 joerg SmallString<256> MappedPathStorage;
136 1.1 joerg StringRef MappedPathStr = Path.toStringRef(MappedPathStorage);
137 1.1 joerg
138 1.1 joerg // If use system headers while cross-compiling, emit the warning.
139 1.1 joerg if (HasSysroot && (MappedPathStr.startswith("/usr/include") ||
140 1.1 joerg MappedPathStr.startswith("/usr/local/include"))) {
141 1.1 joerg Headers.getDiags().Report(diag::warn_poison_system_directories)
142 1.1 joerg << MappedPathStr;
143 1.1 joerg }
144 1.1 joerg
145 1.1 joerg // Compute the DirectoryLookup type.
146 1.1 joerg SrcMgr::CharacteristicKind Type;
147 1.1 joerg if (Group == Quoted || Group == Angled || Group == IndexHeaderMap) {
148 1.1 joerg Type = SrcMgr::C_User;
149 1.1 joerg } else if (Group == ExternCSystem) {
150 1.1 joerg Type = SrcMgr::C_ExternCSystem;
151 1.1 joerg } else {
152 1.1 joerg Type = SrcMgr::C_System;
153 1.1 joerg }
154 1.1 joerg
155 1.1 joerg // If the directory exists, add it.
156 1.1 joerg if (auto DE = FM.getOptionalDirectoryRef(MappedPathStr)) {
157 1.1 joerg IncludePath.push_back(
158 1.1 joerg std::make_pair(Group, DirectoryLookup(*DE, Type, isFramework)));
159 1.1 joerg return true;
160 1.1 joerg }
161 1.1 joerg
162 1.1 joerg // Check to see if this is an apple-style headermap (which are not allowed to
163 1.1 joerg // be frameworks).
164 1.1 joerg if (!isFramework) {
165 1.1 joerg if (auto FE = FM.getFile(MappedPathStr)) {
166 1.1 joerg if (const HeaderMap *HM = Headers.CreateHeaderMap(*FE)) {
167 1.1 joerg // It is a headermap, add it to the search path.
168 1.1 joerg IncludePath.push_back(
169 1.1 joerg std::make_pair(Group,
170 1.1 joerg DirectoryLookup(HM, Type, Group == IndexHeaderMap)));
171 1.1 joerg return true;
172 1.1 joerg }
173 1.1 joerg }
174 1.1 joerg }
175 1.1 joerg
176 1.1 joerg if (Verbose)
177 1.1 joerg llvm::errs() << "ignoring nonexistent directory \""
178 1.1 joerg << MappedPathStr << "\"\n";
179 1.1 joerg return false;
180 1.1 joerg }
181 1.1 joerg
182 1.1 joerg bool InitHeaderSearch::AddGnuCPlusPlusIncludePaths(StringRef Base,
183 1.1 joerg StringRef ArchDir,
184 1.1 joerg StringRef Dir32,
185 1.1 joerg StringRef Dir64,
186 1.1 joerg const llvm::Triple &triple) {
187 1.1 joerg // Add the base dir
188 1.1 joerg bool IsBaseFound = AddPath(Base, CXXSystem, false);
189 1.1 joerg
190 1.1 joerg // Add the multilib dirs
191 1.1 joerg llvm::Triple::ArchType arch = triple.getArch();
192 1.1 joerg bool is64bit = arch == llvm::Triple::ppc64 || arch == llvm::Triple::x86_64;
193 1.1 joerg if (is64bit)
194 1.1 joerg AddPath(Base + "/" + ArchDir + "/" + Dir64, CXXSystem, false);
195 1.1 joerg else
196 1.1 joerg AddPath(Base + "/" + ArchDir + "/" + Dir32, CXXSystem, false);
197 1.1 joerg
198 1.1 joerg // Add the backward dir
199 1.1 joerg AddPath(Base + "/backward", CXXSystem, false);
200 1.1 joerg return IsBaseFound;
201 1.1 joerg }
202 1.1 joerg
203 1.1 joerg void InitHeaderSearch::AddMinGWCPlusPlusIncludePaths(StringRef Base,
204 1.1 joerg StringRef Arch,
205 1.1 joerg StringRef Version) {
206 1.1 joerg AddPath(Base + "/" + Arch + "/" + Version + "/include/c++",
207 1.1 joerg CXXSystem, false);
208 1.1 joerg AddPath(Base + "/" + Arch + "/" + Version + "/include/c++/" + Arch,
209 1.1 joerg CXXSystem, false);
210 1.1 joerg AddPath(Base + "/" + Arch + "/" + Version + "/include/c++/backward",
211 1.1 joerg CXXSystem, false);
212 1.1 joerg }
213 1.1 joerg
214 1.1 joerg void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple,
215 1.1 joerg const HeaderSearchOptions &HSOpts) {
216 1.1 joerg llvm::Triple::OSType os = triple.getOS();
217 1.1 joerg
218 1.1 joerg if (triple.isOSDarwin()) {
219 1.1 joerg llvm_unreachable("Include management is handled in the driver.");
220 1.1 joerg }
221 1.1 joerg
222 1.1 joerg if (HSOpts.UseStandardSystemIncludes) {
223 1.1 joerg switch (os) {
224 1.1 joerg case llvm::Triple::CloudABI:
225 1.1 joerg case llvm::Triple::FreeBSD:
226 1.1 joerg case llvm::Triple::NetBSD:
227 1.1 joerg case llvm::Triple::OpenBSD:
228 1.1 joerg case llvm::Triple::NaCl:
229 1.1 joerg case llvm::Triple::PS4:
230 1.1 joerg case llvm::Triple::ELFIAMCU:
231 1.1 joerg case llvm::Triple::Fuchsia:
232 1.1 joerg break;
233 1.1 joerg case llvm::Triple::Win32:
234 1.1 joerg if (triple.getEnvironment() != llvm::Triple::Cygnus)
235 1.1 joerg break;
236 1.1 joerg LLVM_FALLTHROUGH;
237 1.1 joerg default:
238 1.1 joerg // FIXME: temporary hack: hard-coded paths.
239 1.1 joerg AddPath("/usr/local/include", System, false);
240 1.1 joerg break;
241 1.1 joerg }
242 1.1 joerg }
243 1.1 joerg
244 1.1 joerg // Builtin includes use #include_next directives and should be positioned
245 1.1 joerg // just prior C include dirs.
246 1.1 joerg if (HSOpts.UseBuiltinIncludes) {
247 1.1 joerg // Ignore the sys root, we *always* look for clang headers relative to
248 1.1 joerg // supplied path.
249 1.1 joerg SmallString<128> P = StringRef(HSOpts.ResourceDir);
250 1.1 joerg llvm::sys::path::append(P, "include");
251 1.1 joerg AddUnmappedPath(P, ExternCSystem, false);
252 1.1 joerg }
253 1.1 joerg
254 1.1 joerg // All remaining additions are for system include directories, early exit if
255 1.1 joerg // we aren't using them.
256 1.1 joerg if (!HSOpts.UseStandardSystemIncludes)
257 1.1 joerg return;
258 1.1 joerg
259 1.1 joerg // Add dirs specified via 'configure --with-c-include-dirs'.
260 1.1 joerg StringRef CIncludeDirs(C_INCLUDE_DIRS);
261 1.1 joerg if (CIncludeDirs != "") {
262 1.1 joerg SmallVector<StringRef, 5> dirs;
263 1.1 joerg CIncludeDirs.split(dirs, ":");
264 1.1 joerg for (StringRef dir : dirs)
265 1.1 joerg AddPath(dir, ExternCSystem, false);
266 1.1 joerg return;
267 1.1 joerg }
268 1.1 joerg
269 1.1 joerg switch (os) {
270 1.1 joerg case llvm::Triple::Linux:
271 1.1 joerg case llvm::Triple::Hurd:
272 1.1 joerg case llvm::Triple::Solaris:
273 1.1.1.1.4.1 cjep case llvm::Triple::OpenBSD:
274 1.1 joerg llvm_unreachable("Include management is handled in the driver.");
275 1.1 joerg
276 1.1 joerg case llvm::Triple::CloudABI: {
277 1.1 joerg // <sysroot>/<triple>/include
278 1.1 joerg SmallString<128> P = StringRef(HSOpts.ResourceDir);
279 1.1 joerg llvm::sys::path::append(P, "../../..", triple.str(), "include");
280 1.1 joerg AddPath(P, System, false);
281 1.1 joerg break;
282 1.1 joerg }
283 1.1 joerg
284 1.1 joerg case llvm::Triple::Haiku:
285 1.1 joerg AddPath("/boot/system/non-packaged/develop/headers", System, false);
286 1.1 joerg AddPath("/boot/system/develop/headers/os", System, false);
287 1.1 joerg AddPath("/boot/system/develop/headers/os/app", System, false);
288 1.1 joerg AddPath("/boot/system/develop/headers/os/arch", System, false);
289 1.1 joerg AddPath("/boot/system/develop/headers/os/device", System, false);
290 1.1 joerg AddPath("/boot/system/develop/headers/os/drivers", System, false);
291 1.1 joerg AddPath("/boot/system/develop/headers/os/game", System, false);
292 1.1 joerg AddPath("/boot/system/develop/headers/os/interface", System, false);
293 1.1 joerg AddPath("/boot/system/develop/headers/os/kernel", System, false);
294 1.1 joerg AddPath("/boot/system/develop/headers/os/locale", System, false);
295 1.1 joerg AddPath("/boot/system/develop/headers/os/mail", System, false);
296 1.1 joerg AddPath("/boot/system/develop/headers/os/media", System, false);
297 1.1 joerg AddPath("/boot/system/develop/headers/os/midi", System, false);
298 1.1 joerg AddPath("/boot/system/develop/headers/os/midi2", System, false);
299 1.1 joerg AddPath("/boot/system/develop/headers/os/net", System, false);
300 1.1 joerg AddPath("/boot/system/develop/headers/os/opengl", System, false);
301 1.1 joerg AddPath("/boot/system/develop/headers/os/storage", System, false);
302 1.1 joerg AddPath("/boot/system/develop/headers/os/support", System, false);
303 1.1 joerg AddPath("/boot/system/develop/headers/os/translation", System, false);
304 1.1 joerg AddPath("/boot/system/develop/headers/os/add-ons/graphics", System, false);
305 1.1 joerg AddPath("/boot/system/develop/headers/os/add-ons/input_server", System, false);
306 1.1 joerg AddPath("/boot/system/develop/headers/os/add-ons/mail_daemon", System, false);
307 1.1 joerg AddPath("/boot/system/develop/headers/os/add-ons/registrar", System, false);
308 1.1 joerg AddPath("/boot/system/develop/headers/os/add-ons/screen_saver", System, false);
309 1.1 joerg AddPath("/boot/system/develop/headers/os/add-ons/tracker", System, false);
310 1.1 joerg AddPath("/boot/system/develop/headers/os/be_apps/Deskbar", System, false);
311 1.1 joerg AddPath("/boot/system/develop/headers/os/be_apps/NetPositive", System, false);
312 1.1 joerg AddPath("/boot/system/develop/headers/os/be_apps/Tracker", System, false);
313 1.1 joerg AddPath("/boot/system/develop/headers/3rdparty", System, false);
314 1.1 joerg AddPath("/boot/system/develop/headers/bsd", System, false);
315 1.1 joerg AddPath("/boot/system/develop/headers/glibc", System, false);
316 1.1 joerg AddPath("/boot/system/develop/headers/posix", System, false);
317 1.1 joerg AddPath("/boot/system/develop/headers", System, false);
318 1.1 joerg break;
319 1.1 joerg case llvm::Triple::RTEMS:
320 1.1 joerg break;
321 1.1 joerg case llvm::Triple::Win32:
322 1.1 joerg switch (triple.getEnvironment()) {
323 1.1 joerg default: llvm_unreachable("Include management is handled in the driver.");
324 1.1 joerg case llvm::Triple::Cygnus:
325 1.1 joerg AddPath("/usr/include/w32api", System, false);
326 1.1 joerg break;
327 1.1 joerg case llvm::Triple::GNU:
328 1.1 joerg break;
329 1.1 joerg }
330 1.1 joerg break;
331 1.1 joerg default:
332 1.1 joerg break;
333 1.1 joerg }
334 1.1 joerg
335 1.1 joerg switch (os) {
336 1.1 joerg case llvm::Triple::CloudABI:
337 1.1 joerg case llvm::Triple::RTEMS:
338 1.1 joerg case llvm::Triple::NaCl:
339 1.1 joerg case llvm::Triple::ELFIAMCU:
340 1.1 joerg case llvm::Triple::Fuchsia:
341 1.1 joerg break;
342 1.1 joerg case llvm::Triple::PS4: {
343 1.1 joerg // <isysroot> gets prepended later in AddPath().
344 1.1 joerg std::string BaseSDKPath = "";
345 1.1 joerg if (!HasSysroot) {
346 1.1 joerg const char *envValue = getenv("SCE_ORBIS_SDK_DIR");
347 1.1 joerg if (envValue)
348 1.1 joerg BaseSDKPath = envValue;
349 1.1 joerg else {
350 1.1 joerg // HSOpts.ResourceDir variable contains the location of Clang's
351 1.1 joerg // resource files.
352 1.1 joerg // Assuming that Clang is configured for PS4 without
353 1.1 joerg // --with-clang-resource-dir option, the location of Clang's resource
354 1.1 joerg // files is <SDK_DIR>/host_tools/lib/clang
355 1.1 joerg SmallString<128> P = StringRef(HSOpts.ResourceDir);
356 1.1 joerg llvm::sys::path::append(P, "../../..");
357 1.1.1.1.4.1 cjep BaseSDKPath = std::string(P.str());
358 1.1 joerg }
359 1.1 joerg }
360 1.1 joerg AddPath(BaseSDKPath + "/target/include", System, false);
361 1.1 joerg if (triple.isPS4CPU())
362 1.1 joerg AddPath(BaseSDKPath + "/target/include_common", System, false);
363 1.1 joerg LLVM_FALLTHROUGH;
364 1.1 joerg }
365 1.1 joerg default:
366 1.1 joerg AddPath("/usr/include", ExternCSystem, false);
367 1.1 joerg break;
368 1.1 joerg }
369 1.1 joerg }
370 1.1 joerg
371 1.1 joerg void InitHeaderSearch::AddDefaultCPlusPlusIncludePaths(
372 1.1 joerg const LangOptions &LangOpts, const llvm::Triple &triple,
373 1.1 joerg const HeaderSearchOptions &HSOpts) {
374 1.1 joerg llvm::Triple::OSType os = triple.getOS();
375 1.1 joerg // FIXME: temporary hack: hard-coded paths.
376 1.1 joerg
377 1.1 joerg if (triple.isOSDarwin()) {
378 1.1 joerg llvm_unreachable("Include management is handled in the driver.");
379 1.1 joerg }
380 1.1 joerg
381 1.1 joerg switch (os) {
382 1.1 joerg case llvm::Triple::Linux:
383 1.1 joerg case llvm::Triple::Hurd:
384 1.1 joerg case llvm::Triple::Solaris:
385 1.1.1.1.4.1 cjep case llvm::Triple::AIX:
386 1.1 joerg llvm_unreachable("Include management is handled in the driver.");
387 1.1 joerg break;
388 1.1 joerg case llvm::Triple::Win32:
389 1.1 joerg switch (triple.getEnvironment()) {
390 1.1 joerg default: llvm_unreachable("Include management is handled in the driver.");
391 1.1 joerg case llvm::Triple::Cygnus:
392 1.1 joerg // Cygwin-1.7
393 1.1 joerg AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.7.3");
394 1.1 joerg AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.5.3");
395 1.1 joerg AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.3.4");
396 1.1 joerg // g++-4 / Cygwin-1.5
397 1.1 joerg AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.3.2");
398 1.1 joerg break;
399 1.1 joerg }
400 1.1 joerg break;
401 1.1 joerg case llvm::Triple::DragonFly:
402 1.1 joerg AddPath("/usr/include/c++/5.0", CXXSystem, false);
403 1.1 joerg break;
404 1.1 joerg case llvm::Triple::Minix:
405 1.1 joerg AddGnuCPlusPlusIncludePaths("/usr/gnu/include/c++/4.4.3",
406 1.1 joerg "", "", "", triple);
407 1.1 joerg break;
408 1.1 joerg default:
409 1.1 joerg break;
410 1.1 joerg }
411 1.1 joerg }
412 1.1 joerg
413 1.1 joerg void InitHeaderSearch::AddDefaultIncludePaths(const LangOptions &Lang,
414 1.1 joerg const llvm::Triple &triple,
415 1.1 joerg const HeaderSearchOptions &HSOpts) {
416 1.1 joerg // NB: This code path is going away. All of the logic is moving into the
417 1.1 joerg // driver which has the information necessary to do target-specific
418 1.1 joerg // selections of default include paths. Each target which moves there will be
419 1.1 joerg // exempted from this logic here until we can delete the entire pile of code.
420 1.1 joerg switch (triple.getOS()) {
421 1.1 joerg default:
422 1.1 joerg break; // Everything else continues to use this routine's logic.
423 1.1 joerg
424 1.1 joerg case llvm::Triple::Emscripten:
425 1.1 joerg case llvm::Triple::Linux:
426 1.1 joerg case llvm::Triple::Hurd:
427 1.1.1.1.4.1 cjep case llvm::Triple::OpenBSD:
428 1.1 joerg case llvm::Triple::Solaris:
429 1.1 joerg case llvm::Triple::WASI:
430 1.1.1.1.4.1 cjep case llvm::Triple::AIX:
431 1.1 joerg return;
432 1.1 joerg
433 1.1 joerg case llvm::Triple::Win32:
434 1.1 joerg if (triple.getEnvironment() != llvm::Triple::Cygnus ||
435 1.1 joerg triple.isOSBinFormatMachO())
436 1.1 joerg return;
437 1.1 joerg break;
438 1.1 joerg
439 1.1 joerg case llvm::Triple::UnknownOS:
440 1.1.1.1.4.1 cjep if (triple.isWasm())
441 1.1 joerg return;
442 1.1 joerg break;
443 1.1 joerg }
444 1.1 joerg
445 1.1 joerg // All header search logic is handled in the Driver for Darwin.
446 1.1 joerg if (triple.isOSDarwin()) {
447 1.1 joerg if (HSOpts.UseStandardSystemIncludes) {
448 1.1 joerg // Add the default framework include paths on Darwin.
449 1.1 joerg AddPath("/System/Library/Frameworks", System, true);
450 1.1 joerg AddPath("/Library/Frameworks", System, true);
451 1.1 joerg }
452 1.1 joerg return;
453 1.1 joerg }
454 1.1 joerg
455 1.1 joerg if (Lang.CPlusPlus && !Lang.AsmPreprocessor &&
456 1.1 joerg HSOpts.UseStandardCXXIncludes && HSOpts.UseStandardSystemIncludes) {
457 1.1 joerg if (HSOpts.UseLibcxx) {
458 1.1 joerg AddPath("/usr/include/c++/v1", CXXSystem, false);
459 1.1 joerg } else {
460 1.1 joerg AddDefaultCPlusPlusIncludePaths(Lang, triple, HSOpts);
461 1.1 joerg }
462 1.1 joerg }
463 1.1 joerg
464 1.1 joerg AddDefaultCIncludePaths(triple, HSOpts);
465 1.1 joerg }
466 1.1 joerg
467 1.1 joerg /// RemoveDuplicates - If there are duplicate directory entries in the specified
468 1.1 joerg /// search list, remove the later (dead) ones. Returns the number of non-system
469 1.1 joerg /// headers removed, which is used to update NumAngled.
470 1.1 joerg static unsigned RemoveDuplicates(std::vector<DirectoryLookup> &SearchList,
471 1.1 joerg unsigned First, bool Verbose) {
472 1.1 joerg llvm::SmallPtrSet<const DirectoryEntry *, 8> SeenDirs;
473 1.1 joerg llvm::SmallPtrSet<const DirectoryEntry *, 8> SeenFrameworkDirs;
474 1.1 joerg llvm::SmallPtrSet<const HeaderMap *, 8> SeenHeaderMaps;
475 1.1 joerg unsigned NonSystemRemoved = 0;
476 1.1 joerg for (unsigned i = First; i != SearchList.size(); ++i) {
477 1.1 joerg unsigned DirToRemove = i;
478 1.1 joerg
479 1.1 joerg const DirectoryLookup &CurEntry = SearchList[i];
480 1.1 joerg
481 1.1 joerg if (CurEntry.isNormalDir()) {
482 1.1 joerg // If this isn't the first time we've seen this dir, remove it.
483 1.1 joerg if (SeenDirs.insert(CurEntry.getDir()).second)
484 1.1 joerg continue;
485 1.1 joerg } else if (CurEntry.isFramework()) {
486 1.1 joerg // If this isn't the first time we've seen this framework dir, remove it.
487 1.1 joerg if (SeenFrameworkDirs.insert(CurEntry.getFrameworkDir()).second)
488 1.1 joerg continue;
489 1.1 joerg } else {
490 1.1 joerg assert(CurEntry.isHeaderMap() && "Not a headermap or normal dir?");
491 1.1 joerg // If this isn't the first time we've seen this headermap, remove it.
492 1.1 joerg if (SeenHeaderMaps.insert(CurEntry.getHeaderMap()).second)
493 1.1 joerg continue;
494 1.1 joerg }
495 1.1 joerg
496 1.1 joerg // If we have a normal #include dir/framework/headermap that is shadowed
497 1.1 joerg // later in the chain by a system include location, we actually want to
498 1.1 joerg // ignore the user's request and drop the user dir... keeping the system
499 1.1 joerg // dir. This is weird, but required to emulate GCC's search path correctly.
500 1.1 joerg //
501 1.1 joerg // Since dupes of system dirs are rare, just rescan to find the original
502 1.1 joerg // that we're nuking instead of using a DenseMap.
503 1.1 joerg if (CurEntry.getDirCharacteristic() != SrcMgr::C_User) {
504 1.1 joerg // Find the dir that this is the same of.
505 1.1 joerg unsigned FirstDir;
506 1.1 joerg for (FirstDir = First;; ++FirstDir) {
507 1.1 joerg assert(FirstDir != i && "Didn't find dupe?");
508 1.1 joerg
509 1.1 joerg const DirectoryLookup &SearchEntry = SearchList[FirstDir];
510 1.1 joerg
511 1.1 joerg // If these are different lookup types, then they can't be the dupe.
512 1.1 joerg if (SearchEntry.getLookupType() != CurEntry.getLookupType())
513 1.1 joerg continue;
514 1.1 joerg
515 1.1 joerg bool isSame;
516 1.1 joerg if (CurEntry.isNormalDir())
517 1.1 joerg isSame = SearchEntry.getDir() == CurEntry.getDir();
518 1.1 joerg else if (CurEntry.isFramework())
519 1.1 joerg isSame = SearchEntry.getFrameworkDir() == CurEntry.getFrameworkDir();
520 1.1 joerg else {
521 1.1 joerg assert(CurEntry.isHeaderMap() && "Not a headermap or normal dir?");
522 1.1 joerg isSame = SearchEntry.getHeaderMap() == CurEntry.getHeaderMap();
523 1.1 joerg }
524 1.1 joerg
525 1.1 joerg if (isSame)
526 1.1 joerg break;
527 1.1 joerg }
528 1.1 joerg
529 1.1 joerg // If the first dir in the search path is a non-system dir, zap it
530 1.1 joerg // instead of the system one.
531 1.1 joerg if (SearchList[FirstDir].getDirCharacteristic() == SrcMgr::C_User)
532 1.1 joerg DirToRemove = FirstDir;
533 1.1 joerg }
534 1.1 joerg
535 1.1 joerg if (Verbose) {
536 1.1 joerg llvm::errs() << "ignoring duplicate directory \""
537 1.1 joerg << CurEntry.getName() << "\"\n";
538 1.1 joerg if (DirToRemove != i)
539 1.1 joerg llvm::errs() << " as it is a non-system directory that duplicates "
540 1.1 joerg << "a system directory\n";
541 1.1 joerg }
542 1.1 joerg if (DirToRemove != i)
543 1.1 joerg ++NonSystemRemoved;
544 1.1 joerg
545 1.1 joerg // This is reached if the current entry is a duplicate. Remove the
546 1.1 joerg // DirToRemove (usually the current dir).
547 1.1 joerg SearchList.erase(SearchList.begin()+DirToRemove);
548 1.1 joerg --i;
549 1.1 joerg }
550 1.1 joerg return NonSystemRemoved;
551 1.1 joerg }
552 1.1 joerg
553 1.1 joerg
554 1.1 joerg void InitHeaderSearch::Realize(const LangOptions &Lang) {
555 1.1 joerg // Concatenate ANGLE+SYSTEM+AFTER chains together into SearchList.
556 1.1 joerg std::vector<DirectoryLookup> SearchList;
557 1.1 joerg SearchList.reserve(IncludePath.size());
558 1.1 joerg
559 1.1 joerg // Quoted arguments go first.
560 1.1 joerg for (auto &Include : IncludePath)
561 1.1 joerg if (Include.first == Quoted)
562 1.1 joerg SearchList.push_back(Include.second);
563 1.1 joerg
564 1.1 joerg // Deduplicate and remember index.
565 1.1 joerg RemoveDuplicates(SearchList, 0, Verbose);
566 1.1 joerg unsigned NumQuoted = SearchList.size();
567 1.1 joerg
568 1.1 joerg for (auto &Include : IncludePath)
569 1.1 joerg if (Include.first == Angled || Include.first == IndexHeaderMap)
570 1.1 joerg SearchList.push_back(Include.second);
571 1.1 joerg
572 1.1 joerg RemoveDuplicates(SearchList, NumQuoted, Verbose);
573 1.1 joerg unsigned NumAngled = SearchList.size();
574 1.1 joerg
575 1.1 joerg for (auto &Include : IncludePath)
576 1.1 joerg if (Include.first == System || Include.first == ExternCSystem ||
577 1.1 joerg (!Lang.ObjC && !Lang.CPlusPlus && Include.first == CSystem) ||
578 1.1 joerg (/*FIXME !Lang.ObjC && */ Lang.CPlusPlus &&
579 1.1 joerg Include.first == CXXSystem) ||
580 1.1 joerg (Lang.ObjC && !Lang.CPlusPlus && Include.first == ObjCSystem) ||
581 1.1 joerg (Lang.ObjC && Lang.CPlusPlus && Include.first == ObjCXXSystem))
582 1.1 joerg SearchList.push_back(Include.second);
583 1.1 joerg
584 1.1 joerg for (auto &Include : IncludePath)
585 1.1 joerg if (Include.first == After)
586 1.1 joerg SearchList.push_back(Include.second);
587 1.1 joerg
588 1.1 joerg // Remove duplicates across both the Angled and System directories. GCC does
589 1.1 joerg // this and failing to remove duplicates across these two groups breaks
590 1.1 joerg // #include_next.
591 1.1 joerg unsigned NonSystemRemoved = RemoveDuplicates(SearchList, NumQuoted, Verbose);
592 1.1 joerg NumAngled -= NonSystemRemoved;
593 1.1 joerg
594 1.1 joerg bool DontSearchCurDir = false; // TODO: set to true if -I- is set?
595 1.1 joerg Headers.SetSearchPaths(SearchList, NumQuoted, NumAngled, DontSearchCurDir);
596 1.1 joerg
597 1.1 joerg Headers.SetSystemHeaderPrefixes(SystemHeaderPrefixes);
598 1.1 joerg
599 1.1 joerg // If verbose, print the list of directories that will be searched.
600 1.1 joerg if (Verbose) {
601 1.1 joerg llvm::errs() << "#include \"...\" search starts here:\n";
602 1.1 joerg for (unsigned i = 0, e = SearchList.size(); i != e; ++i) {
603 1.1 joerg if (i == NumQuoted)
604 1.1 joerg llvm::errs() << "#include <...> search starts here:\n";
605 1.1 joerg StringRef Name = SearchList[i].getName();
606 1.1 joerg const char *Suffix;
607 1.1 joerg if (SearchList[i].isNormalDir())
608 1.1 joerg Suffix = "";
609 1.1 joerg else if (SearchList[i].isFramework())
610 1.1 joerg Suffix = " (framework directory)";
611 1.1 joerg else {
612 1.1 joerg assert(SearchList[i].isHeaderMap() && "Unknown DirectoryLookup");
613 1.1 joerg Suffix = " (headermap)";
614 1.1 joerg }
615 1.1 joerg llvm::errs() << " " << Name << Suffix << "\n";
616 1.1 joerg }
617 1.1 joerg llvm::errs() << "End of search list.\n";
618 1.1 joerg }
619 1.1 joerg }
620 1.1 joerg
621 1.1 joerg void clang::ApplyHeaderSearchOptions(HeaderSearch &HS,
622 1.1 joerg const HeaderSearchOptions &HSOpts,
623 1.1 joerg const LangOptions &Lang,
624 1.1 joerg const llvm::Triple &Triple) {
625 1.1 joerg InitHeaderSearch Init(HS, HSOpts.Verbose, HSOpts.Sysroot);
626 1.1 joerg
627 1.1 joerg // Add the user defined entries.
628 1.1 joerg for (unsigned i = 0, e = HSOpts.UserEntries.size(); i != e; ++i) {
629 1.1 joerg const HeaderSearchOptions::Entry &E = HSOpts.UserEntries[i];
630 1.1 joerg if (E.IgnoreSysRoot) {
631 1.1 joerg Init.AddUnmappedPath(E.Path, E.Group, E.IsFramework);
632 1.1 joerg } else {
633 1.1 joerg Init.AddPath(E.Path, E.Group, E.IsFramework);
634 1.1 joerg }
635 1.1 joerg }
636 1.1 joerg
637 1.1 joerg Init.AddDefaultIncludePaths(Lang, Triple, HSOpts);
638 1.1 joerg
639 1.1 joerg for (unsigned i = 0, e = HSOpts.SystemHeaderPrefixes.size(); i != e; ++i)
640 1.1 joerg Init.AddSystemHeaderPrefix(HSOpts.SystemHeaderPrefixes[i].Prefix,
641 1.1 joerg HSOpts.SystemHeaderPrefixes[i].IsSystemHeader);
642 1.1 joerg
643 1.1 joerg if (HSOpts.UseBuiltinIncludes) {
644 1.1 joerg // Set up the builtin include directory in the module map.
645 1.1 joerg SmallString<128> P = StringRef(HSOpts.ResourceDir);
646 1.1 joerg llvm::sys::path::append(P, "include");
647 1.1 joerg if (auto Dir = HS.getFileMgr().getDirectory(P))
648 1.1 joerg HS.getModuleMap().setBuiltinIncludeDir(*Dir);
649 1.1 joerg }
650 1.1 joerg
651 1.1 joerg Init.Realize(Lang);
652 1.1 joerg }
653