Skip to content

Commit 8404eb0

Browse files
committed
Add support for CPATH and friends.
This moves the existing code for CPATH into the driver and adds the environment lookup and path splitting there. The paths are then passed down to cc1 with -I options (CPATH), added after the normal user-specified include dirs. Language specific paths are passed via -LANG-isystem and the actual filtering is performed in the frontend. I tried to match GCC's behavior as close as possible Fixes PR8971. llvm-svn: 140341
1 parent e92e5ee commit 8404eb0

File tree

6 files changed

+115
-75
lines changed

6 files changed

+115
-75
lines changed

clang/include/clang/Driver/CC1Options.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -623,8 +623,16 @@ def index_header_map : Flag<"-index-header-map">,
623623
HelpText<"Make the next included directory (-I or -F) an indexer header map">;
624624
def iquote : JoinedOrSeparate<"-iquote">, MetaVarName<"<directory>">,
625625
HelpText<"Add directory to QUOTE include search path">;
626+
def c_isystem : JoinedOrSeparate<"-c-isystem">, MetaVarName<"<directory>">,
627+
HelpText<"Add directory to the C SYSTEM include search path">;
626628
def cxx_isystem : JoinedOrSeparate<"-cxx-isystem">, MetaVarName<"<directory>">,
627629
HelpText<"Add directory to the C++ SYSTEM include search path">;
630+
def objc_isystem : JoinedOrSeparate<"-objc-isystem">,
631+
MetaVarName<"<directory>">,
632+
HelpText<"Add directory to the ObjC SYSTEM include search path">;
633+
def objcxx_isystem : JoinedOrSeparate<"-objcxx-isystem">,
634+
MetaVarName<"<directory>">,
635+
HelpText<"Add directory to the ObjC++ SYSTEM include search path">;
628636
def isystem : JoinedOrSeparate<"-isystem">, MetaVarName<"<directory>">,
629637
HelpText<"Add directory to SYSTEM include search path">;
630638
def iwithsysroot : JoinedOrSeparate<"-iwithsysroot">,MetaVarName<"<directory>">,

clang/include/clang/Frontend/HeaderSearchOptions.h

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@ namespace frontend {
2626
IndexHeaderMap, ///< Like Angled, but marks header maps used when
2727
/// building frameworks.
2828
System, ///< Like Angled, but marks system directories.
29+
CSystem, ///< Like System, but only used for C.
2930
CXXSystem, ///< Like System, but only used for C++.
31+
ObjCSystem, ///< Like System, but only used for ObjC.
32+
ObjCXXSystem, ///< Like System, but only used for ObjC++.
3033
After ///< Like System, but searched after the system directories.
3134
};
3235
}
@@ -59,18 +62,6 @@ class HeaderSearchOptions {
5962
/// User specified include entries.
6063
std::vector<Entry> UserEntries;
6164

62-
/// A (system-path) delimited list of include paths to be added from the
63-
/// environment following the user specified includes (but prior to builtin
64-
/// and standard includes). This is parsed in the same manner as the CPATH
65-
/// environment variable for gcc.
66-
std::string EnvIncPath;
67-
68-
/// Per-language environmental include paths, see \see EnvIncPath.
69-
std::string CEnvIncPath;
70-
std::string ObjCEnvIncPath;
71-
std::string CXXEnvIncPath;
72-
std::string ObjCXXEnvIncPath;
73-
7465
/// The directory which holds the compiler resource files (builtin includes,
7566
/// etc.).
7667
std::string ResourceDir;

clang/lib/Driver/Tools.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,38 @@ static void addProfileRT(const ToolChain &TC, const ArgList &Args,
183183
CmdArgs.push_back(Args.MakeArgString(ProfileRT));
184184
}
185185

186+
static void AddIncludeDirectoryList(const ArgList &Args,
187+
ArgStringList &CmdArgs,
188+
const char *ArgName,
189+
const char *DirList) {
190+
if (!DirList)
191+
return; // Nothing to do.
192+
193+
StringRef Dirs(DirList);
194+
if (Dirs.empty()) // Empty string should not add '.'.
195+
return;
196+
197+
StringRef::size_type Delim;
198+
while ((Delim = Dirs.find(llvm::sys::PathSeparator)) != StringRef::npos) {
199+
if (Delim == 0) { // Leading colon.
200+
CmdArgs.push_back(ArgName);
201+
CmdArgs.push_back(".");
202+
} else {
203+
CmdArgs.push_back(ArgName);
204+
CmdArgs.push_back(Args.MakeArgString(Dirs.substr(0, Delim)));
205+
}
206+
Dirs = Dirs.substr(Delim + 1);
207+
}
208+
209+
if (Dirs.empty()) { // Trailing colon.
210+
CmdArgs.push_back(ArgName);
211+
CmdArgs.push_back(".");
212+
} else { // Add the last path.
213+
CmdArgs.push_back(ArgName);
214+
CmdArgs.push_back(Args.MakeArgString(Dirs));
215+
}
216+
}
217+
186218
void Clang::AddPreprocessingOptions(const Driver &D,
187219
const ArgList &Args,
188220
ArgStringList &CmdArgs,
@@ -391,6 +423,23 @@ void Clang::AddPreprocessingOptions(const Driver &D,
391423
}
392424

393425
Args.AddAllArgs(CmdArgs, options::OPT_fauto_module_import);
426+
427+
// Parse additional include paths from environment variables.
428+
// CPATH - included following the user specified includes (but prior to
429+
// builtin and standard includes).
430+
AddIncludeDirectoryList(Args, CmdArgs, "-I", ::getenv("CPATH"));
431+
// C_INCLUDE_PATH - system includes enabled when compiling C.
432+
AddIncludeDirectoryList(Args, CmdArgs, "-c-isystem",
433+
::getenv("C_INCLUDE_PATH"));
434+
// CPLUS_INCLUDE_PATH - system includes enabled when compiling C++.
435+
AddIncludeDirectoryList(Args, CmdArgs, "-cxx-isystem",
436+
::getenv("CPLUS_INCLUDE_PATH"));
437+
// OBJC_INCLUDE_PATH - system includes enabled when compiling ObjC.
438+
AddIncludeDirectoryList(Args, CmdArgs, "-objc-isystem",
439+
::getenv("OBJC_INCLUDE_PATH"));
440+
// OBJCPLUS_INCLUDE_PATH - system includes enabled when compiling ObjC++.
441+
AddIncludeDirectoryList(Args, CmdArgs, "-objcxx-isystem",
442+
::getenv("OBJCPLUS_INCLUDE_PATH"));
394443
}
395444

396445
/// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targeting.

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -534,9 +534,21 @@ static void HeaderSearchOptsToArgs(const HeaderSearchOptions &Opts,
534534
Res.push_back(E.IsFramework? "-F" : "-I");
535535
break;
536536

537+
case frontend::CSystem:
538+
Res.push_back("-c-isystem");
539+
break;
540+
537541
case frontend::CXXSystem:
538542
Res.push_back("-cxx-isystem");
539543
break;
544+
545+
case frontend::ObjCSystem:
546+
Res.push_back("-objc-isystem");
547+
break;
548+
549+
case frontend::ObjCXXSystem:
550+
Res.push_back("-objcxx-isystem");
551+
break;
540552

541553
case frontend::Angled:
542554
Res.push_back(E.IsFramework ? "-F" : "-I");
@@ -551,26 +563,6 @@ static void HeaderSearchOptsToArgs(const HeaderSearchOptions &Opts,
551563
Res.push_back(E.Path);
552564
}
553565

554-
if (!Opts.EnvIncPath.empty()) {
555-
// FIXME: Provide an option for this, and move env detection to driver.
556-
llvm::report_fatal_error("Not yet implemented!");
557-
}
558-
if (!Opts.CEnvIncPath.empty()) {
559-
// FIXME: Provide an option for this, and move env detection to driver.
560-
llvm::report_fatal_error("Not yet implemented!");
561-
}
562-
if (!Opts.ObjCEnvIncPath.empty()) {
563-
// FIXME: Provide an option for this, and move env detection to driver.
564-
llvm::report_fatal_error("Not yet implemented!");
565-
}
566-
if (!Opts.CXXEnvIncPath.empty()) {
567-
// FIXME: Provide an option for this, and move env detection to driver.
568-
llvm::report_fatal_error("Not yet implemented!");
569-
}
570-
if (!Opts.ObjCXXEnvIncPath.empty()) {
571-
// FIXME: Provide an option for this, and move env detection to driver.
572-
llvm::report_fatal_error("Not yet implemented!");
573-
}
574566
if (!Opts.ResourceDir.empty()) {
575567
Res.push_back("-resource-dir");
576568
Res.push_back(Opts.ResourceDir);
@@ -1424,14 +1416,25 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args) {
14241416
for (arg_iterator it = Args.filtered_begin(OPT_iquote),
14251417
ie = Args.filtered_end(); it != ie; ++it)
14261418
Opts.AddPath((*it)->getValue(Args), frontend::Quoted, true, false, false);
1427-
for (arg_iterator it = Args.filtered_begin(OPT_cxx_isystem, OPT_isystem,
1419+
for (arg_iterator it = Args.filtered_begin(OPT_isystem,
14281420
OPT_iwithsysroot), ie = Args.filtered_end(); it != ie; ++it)
1429-
Opts.AddPath((*it)->getValue(Args),
1430-
((*it)->getOption().matches(OPT_cxx_isystem) ?
1431-
frontend::CXXSystem : frontend::System),
1432-
true, false, !(*it)->getOption().matches(OPT_iwithsysroot));
1433-
1434-
// FIXME: Need options for the various environment variables!
1421+
Opts.AddPath((*it)->getValue(Args), frontend::System, true, false,
1422+
!(*it)->getOption().matches(OPT_iwithsysroot));
1423+
1424+
// Add the paths for the various language specific isystem flags.
1425+
for (arg_iterator it = Args.filtered_begin(OPT_c_isystem),
1426+
ie = Args.filtered_end(); it != ie; ++it)
1427+
Opts.AddPath((*it)->getValue(Args), frontend::CSystem, true, false, true);
1428+
for (arg_iterator it = Args.filtered_begin(OPT_cxx_isystem),
1429+
ie = Args.filtered_end(); it != ie; ++it)
1430+
Opts.AddPath((*it)->getValue(Args), frontend::CXXSystem, true, false, true);
1431+
for (arg_iterator it = Args.filtered_begin(OPT_objc_isystem),
1432+
ie = Args.filtered_end(); it != ie; ++it)
1433+
Opts.AddPath((*it)->getValue(Args), frontend::ObjCSystem, true, false,true);
1434+
for (arg_iterator it = Args.filtered_begin(OPT_objcxx_isystem),
1435+
ie = Args.filtered_end(); it != ie; ++it)
1436+
Opts.AddPath((*it)->getValue(Args), frontend::ObjCXXSystem, true, false,
1437+
true);
14351438
}
14361439

14371440
void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK,

clang/lib/Frontend/InitHeaderSearch.cpp

Lines changed: 5 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,6 @@ class InitHeaderSearch {
8181
void AddMinGW64CXXPaths(StringRef Base,
8282
StringRef Version);
8383

84-
/// AddDelimitedPaths - Add a list of paths delimited by the system PATH
85-
/// separator. The processing follows that of the CPATH variable for gcc.
86-
void AddDelimitedPaths(StringRef String);
87-
8884
// AddDefaultCIncludePaths - Add paths that should always be searched.
8985
void AddDefaultCIncludePaths(const llvm::Triple &triple,
9086
const HeaderSearchOptions &HSOpts);
@@ -167,26 +163,6 @@ void InitHeaderSearch::AddPath(const Twine &Path,
167163
<< MappedPathStr << "\"\n";
168164
}
169165

170-
171-
void InitHeaderSearch::AddDelimitedPaths(StringRef at) {
172-
if (at.empty()) // Empty string should not add '.' path.
173-
return;
174-
175-
StringRef::size_type delim;
176-
while ((delim = at.find(llvm::sys::PathSeparator)) != StringRef::npos) {
177-
if (delim == 0)
178-
AddPath(".", Angled, false, true, false);
179-
else
180-
AddPath(at.substr(0, delim), Angled, false, true, false);
181-
at = at.substr(delim + 1);
182-
}
183-
184-
if (at.empty())
185-
AddPath(".", Angled, false, true, false);
186-
else
187-
AddPath(at, Angled, false, true, false);
188-
}
189-
190166
void InitHeaderSearch::AddGnuCPlusPlusIncludePaths(StringRef Base,
191167
StringRef ArchDir,
192168
StringRef Dir32,
@@ -1094,7 +1070,11 @@ void InitHeaderSearch::Realize(const LangOptions &Lang) {
10941070

10951071
for (path_iterator it = IncludePath.begin(), ie = IncludePath.end();
10961072
it != ie; ++it) {
1097-
if (it->first == System || (Lang.CPlusPlus && it->first == CXXSystem))
1073+
if (it->first == System ||
1074+
(!Lang.ObjC1 && !Lang.CPlusPlus && it->first == CSystem) ||
1075+
(!Lang.ObjC1 && Lang.CPlusPlus && it->first == CXXSystem) ||
1076+
(Lang.ObjC1 && !Lang.CPlusPlus && it->first == ObjCSystem) ||
1077+
(Lang.ObjC1 && Lang.CPlusPlus && it->first == ObjCXXSystem))
10981078
SearchList.push_back(it->second);
10991079
}
11001080

@@ -1147,17 +1127,6 @@ void clang::ApplyHeaderSearchOptions(HeaderSearch &HS,
11471127
E.IgnoreSysRoot);
11481128
}
11491129

1150-
// Add entries from CPATH and friends.
1151-
Init.AddDelimitedPaths(HSOpts.EnvIncPath);
1152-
if (Lang.CPlusPlus && Lang.ObjC1)
1153-
Init.AddDelimitedPaths(HSOpts.ObjCXXEnvIncPath);
1154-
else if (Lang.CPlusPlus)
1155-
Init.AddDelimitedPaths(HSOpts.CXXEnvIncPath);
1156-
else if (Lang.ObjC1)
1157-
Init.AddDelimitedPaths(HSOpts.ObjCEnvIncPath);
1158-
else
1159-
Init.AddDelimitedPaths(HSOpts.CEnvIncPath);
1160-
11611130
if (HSOpts.UseStandardIncludes)
11621131
Init.AddDefaultSystemIncludePaths(Lang, Triple, HSOpts);
11631132

clang/test/Driver/cpath.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// RUN: mkdir -p %T/test1 %T/test2
2+
3+
// RUN: CPATH=%T/test1: %clang -x c -E -v %s 2>&1 | FileCheck %s -check-prefix=CPATH
4+
// CPATH: -I {{.*}}/test1 -I .
5+
// CPATH: search starts here
6+
// CPATH: test1
7+
8+
// RUN: OBJC_INCLUDE_PATH=%T/test1 OBJCPLUS_INCLUDE_PATH=%T/test1 CPLUS_INCLUDE_PATH=%T/test1 C_INCLUDE_PATH=%T/test2 %clang -x c -E -v %s 2>&1 | FileCheck %s -check-prefix=C_INCLUDE_PATH
9+
// C_INCLUDE_PATH: -c-isystem {{.*}}/test2 -cxx-isystem {{.*}}/test1 -objc-isystem {{.*}}/test1 -objcxx-isystem {{.*}}/test1
10+
// C_INCLUDE_PATH: search starts here
11+
// C_INCLUDE_PATH-NOT: test1
12+
// C_INCLUDE_PATH: test2
13+
// C_INCLUDE_PATH-NOT: test1
14+
15+
// RUN: OBJC_INCLUDE_PATH=%T/test1 OBJCPLUS_INCLUDE_PATH=%T/test2 CPLUS_INCLUDE_PATH=%T/test1 C_INCLUDE_PATH=%T/test1 %clang -x objective-c++ -E -v %s 2>&1 | FileCheck %s -check-prefix=OBJCPLUS_INCLUDE_PATH
16+
// OBJCPLUS_INCLUDE_PATH: -c-isystem {{.*}}/test1 -cxx-isystem {{.*}}/test1 -objc-isystem {{.*}}/test1 -objcxx-isystem {{.*}}/test2
17+
// OBJCPLUS_INCLUDE_PATH: search starts here
18+
// OBJCPLUS_INCLUDE_PATH-NOT: test1
19+
// OBJCPLUS_INCLUDE_PATH: test2
20+
// OBJCPLUS_INCLUDE_PATH-NOT: test1

0 commit comments

Comments
 (0)