clang-cc: Move HeaderSearchOptions to Options.cpp

llvm-svn: 86818
This commit is contained in:
Daniel Dunbar 2009-11-11 08:13:32 +00:00
parent b6bac22d02
commit f527a12e47
3 changed files with 176 additions and 161 deletions

View File

@ -13,6 +13,7 @@
#include "Options.h"
#include "clang/Frontend/CompileOptions.h"
#include "clang/Frontend/HeaderSearchOptions.h"
#include "clang/Frontend/PCHReader.h"
#include "clang/Frontend/PreprocessorOptions.h"
#include "clang/Basic/LangOptions.h"
@ -327,6 +328,58 @@ UndefMacros("undef", llvm::cl::value_desc("macro"),
}
//===----------------------------------------------------------------------===//
// Header Search Options
//===----------------------------------------------------------------------===//
namespace headersearchoptions {
static llvm::cl::opt<bool>
nostdinc("nostdinc", llvm::cl::desc("Disable standard #include directories"));
static llvm::cl::opt<bool>
nobuiltininc("nobuiltininc",
llvm::cl::desc("Disable builtin #include directories"));
// Various command line options. These four add directories to each chain.
static llvm::cl::list<std::string>
F_dirs("F", llvm::cl::value_desc("directory"), llvm::cl::Prefix,
llvm::cl::desc("Add directory to framework include search path"));
static llvm::cl::list<std::string>
I_dirs("I", llvm::cl::value_desc("directory"), llvm::cl::Prefix,
llvm::cl::desc("Add directory to include search path"));
static llvm::cl::list<std::string>
idirafter_dirs("idirafter", llvm::cl::value_desc("directory"), llvm::cl::Prefix,
llvm::cl::desc("Add directory to AFTER include search path"));
static llvm::cl::list<std::string>
iquote_dirs("iquote", llvm::cl::value_desc("directory"), llvm::cl::Prefix,
llvm::cl::desc("Add directory to QUOTE include search path"));
static llvm::cl::list<std::string>
isystem_dirs("isystem", llvm::cl::value_desc("directory"), llvm::cl::Prefix,
llvm::cl::desc("Add directory to SYSTEM include search path"));
// These handle -iprefix/-iwithprefix/-iwithprefixbefore.
static llvm::cl::list<std::string>
iprefix_vals("iprefix", llvm::cl::value_desc("prefix"), llvm::cl::Prefix,
llvm::cl::desc("Set the -iwithprefix/-iwithprefixbefore prefix"));
static llvm::cl::list<std::string>
iwithprefix_vals("iwithprefix", llvm::cl::value_desc("dir"), llvm::cl::Prefix,
llvm::cl::desc("Set directory to SYSTEM include search path with prefix"));
static llvm::cl::list<std::string>
iwithprefixbefore_vals("iwithprefixbefore", llvm::cl::value_desc("dir"),
llvm::cl::Prefix,
llvm::cl::desc("Set directory to include search path with prefix"));
static llvm::cl::opt<std::string>
isysroot("isysroot", llvm::cl::value_desc("dir"), llvm::cl::init("/"),
llvm::cl::desc("Set the system root directory (usually /)"));
}
//===----------------------------------------------------------------------===//
// Option Object Construction
//===----------------------------------------------------------------------===//
@ -401,6 +454,111 @@ void clang::InitializeCompileOptions(CompileOptions &Opts,
Opts.MergeAllConstants = !NoMergeConstants;
}
void clang::InitializeHeaderSearchOptions(HeaderSearchOptions &Opts,
llvm::StringRef BuiltinIncludePath,
bool Verbose,
const LangOptions &Lang) {
using namespace headersearchoptions;
Opts.Sysroot = isysroot;
Opts.Verbose = Verbose;
// Handle -I... and -F... options, walking the lists in parallel.
unsigned Iidx = 0, Fidx = 0;
while (Iidx < I_dirs.size() && Fidx < F_dirs.size()) {
if (I_dirs.getPosition(Iidx) < F_dirs.getPosition(Fidx)) {
Opts.AddPath(I_dirs[Iidx], frontend::Angled, false, true, false);
++Iidx;
} else {
Opts.AddPath(F_dirs[Fidx], frontend::Angled, false, true, true);
++Fidx;
}
}
// Consume what's left from whatever list was longer.
for (; Iidx != I_dirs.size(); ++Iidx)
Opts.AddPath(I_dirs[Iidx], frontend::Angled, false, true, false);
for (; Fidx != F_dirs.size(); ++Fidx)
Opts.AddPath(F_dirs[Fidx], frontend::Angled, false, true, true);
// Handle -idirafter... options.
for (unsigned i = 0, e = idirafter_dirs.size(); i != e; ++i)
Opts.AddPath(idirafter_dirs[i], frontend::After,
false, true, false);
// Handle -iquote... options.
for (unsigned i = 0, e = iquote_dirs.size(); i != e; ++i)
Opts.AddPath(iquote_dirs[i], frontend::Quoted, false, true, false);
// Handle -isystem... options.
for (unsigned i = 0, e = isystem_dirs.size(); i != e; ++i)
Opts.AddPath(isystem_dirs[i], frontend::System, false, true, false);
// Walk the -iprefix/-iwithprefix/-iwithprefixbefore argument lists in
// parallel, processing the values in order of occurance to get the right
// prefixes.
{
std::string Prefix = ""; // FIXME: this isn't the correct default prefix.
unsigned iprefix_idx = 0;
unsigned iwithprefix_idx = 0;
unsigned iwithprefixbefore_idx = 0;
bool iprefix_done = iprefix_vals.empty();
bool iwithprefix_done = iwithprefix_vals.empty();
bool iwithprefixbefore_done = iwithprefixbefore_vals.empty();
while (!iprefix_done || !iwithprefix_done || !iwithprefixbefore_done) {
if (!iprefix_done &&
(iwithprefix_done ||
iprefix_vals.getPosition(iprefix_idx) <
iwithprefix_vals.getPosition(iwithprefix_idx)) &&
(iwithprefixbefore_done ||
iprefix_vals.getPosition(iprefix_idx) <
iwithprefixbefore_vals.getPosition(iwithprefixbefore_idx))) {
Prefix = iprefix_vals[iprefix_idx];
++iprefix_idx;
iprefix_done = iprefix_idx == iprefix_vals.size();
} else if (!iwithprefix_done &&
(iwithprefixbefore_done ||
iwithprefix_vals.getPosition(iwithprefix_idx) <
iwithprefixbefore_vals.getPosition(iwithprefixbefore_idx))) {
Opts.AddPath(Prefix+iwithprefix_vals[iwithprefix_idx],
frontend::System, false, false, false);
++iwithprefix_idx;
iwithprefix_done = iwithprefix_idx == iwithprefix_vals.size();
} else {
Opts.AddPath(Prefix+iwithprefixbefore_vals[iwithprefixbefore_idx],
frontend::Angled, false, false, false);
++iwithprefixbefore_idx;
iwithprefixbefore_done =
iwithprefixbefore_idx == iwithprefixbefore_vals.size();
}
}
}
// Add CPATH environment paths.
if (const char *Env = getenv("CPATH"))
Opts.EnvIncPath = Env;
// Add language specific environment paths.
if (Lang.CPlusPlus && Lang.ObjC1) {
if (const char *Env = getenv("OBJCPLUS_INCLUDE_PATH"))
Opts.LangEnvIncPath = Env;
} else if (Lang.CPlusPlus) {
if (const char *Env = getenv("CPLUS_INCLUDE_PATH"))
Opts.LangEnvIncPath = Env;
} else if (Lang.ObjC1) {
if (const char *Env = getenv("OBJC_INCLUDE_PATH"))
Opts.LangEnvIncPath = Env;
} else {
if (const char *Env = getenv("C_INCLUDE_PATH"))
Opts.LangEnvIncPath = Env;
}
if (!nobuiltininc)
Opts.BuiltinIncludePath = BuiltinIncludePath;
Opts.UseStandardIncludes = !nostdinc;
}
void clang::InitializePreprocessorOptions(PreprocessorOptions &Opts) {
using namespace preprocessoroptions;

View File

@ -15,6 +15,7 @@
namespace clang {
class CompileOptions;
class HeaderSearchOptions;
class LangOptions;
class PreprocessorOptions;
class TargetInfo;
@ -41,6 +42,11 @@ void ComputeFeatureMap(TargetInfo &Target, llvm::StringMap<bool> &Features);
void InitializeCompileOptions(CompileOptions &Opts,
const llvm::StringMap<bool> &Features);
void InitializeHeaderSearchOptions(HeaderSearchOptions &Opts,
llvm::StringRef BuiltinIncludePath,
bool Verbose,
const LangOptions &Lang);
void InitializeLangOptions(LangOptions &Options, LangKind LK,
TargetInfo &Target,
const CompileOptions &CompileOpts,

View File

@ -24,7 +24,6 @@
#include "clang/Frontend/DiagnosticOptions.h"
#include "clang/Frontend/FixItRewriter.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/HeaderSearchOptions.h"
#include "clang/Frontend/PCHReader.h"
#include "clang/Frontend/PathDiagnosticClients.h"
#include "clang/Frontend/PreprocessorOptions.h"
@ -408,54 +407,6 @@ RelocatablePCH("relocatable-pch",
llvm::cl::desc("Whether to build a relocatable precompiled "
"header"));
//===----------------------------------------------------------------------===//
// Preprocessor include path information.
//===----------------------------------------------------------------------===//
// This tool exports a large number of command line options to control how the
// preprocessor searches for header files. At root, however, the Preprocessor
// object takes a very simple interface: a list of directories to search for
static llvm::cl::opt<bool>
nostdinc("nostdinc", llvm::cl::desc("Disable standard #include directories"));
static llvm::cl::opt<bool>
nobuiltininc("nobuiltininc",
llvm::cl::desc("Disable builtin #include directories"));
// Various command line options. These four add directories to each chain.
static llvm::cl::list<std::string>
F_dirs("F", llvm::cl::value_desc("directory"), llvm::cl::Prefix,
llvm::cl::desc("Add directory to framework include search path"));
static llvm::cl::list<std::string>
I_dirs("I", llvm::cl::value_desc("directory"), llvm::cl::Prefix,
llvm::cl::desc("Add directory to include search path"));
static llvm::cl::list<std::string>
idirafter_dirs("idirafter", llvm::cl::value_desc("directory"), llvm::cl::Prefix,
llvm::cl::desc("Add directory to AFTER include search path"));
static llvm::cl::list<std::string>
iquote_dirs("iquote", llvm::cl::value_desc("directory"), llvm::cl::Prefix,
llvm::cl::desc("Add directory to QUOTE include search path"));
static llvm::cl::list<std::string>
isystem_dirs("isystem", llvm::cl::value_desc("directory"), llvm::cl::Prefix,
llvm::cl::desc("Add directory to SYSTEM include search path"));
// These handle -iprefix/-iwithprefix/-iwithprefixbefore.
static llvm::cl::list<std::string>
iprefix_vals("iprefix", llvm::cl::value_desc("prefix"), llvm::cl::Prefix,
llvm::cl::desc("Set the -iwithprefix/-iwithprefixbefore prefix"));
static llvm::cl::list<std::string>
iwithprefix_vals("iwithprefix", llvm::cl::value_desc("dir"), llvm::cl::Prefix,
llvm::cl::desc("Set directory to SYSTEM include search path with prefix"));
static llvm::cl::list<std::string>
iwithprefixbefore_vals("iwithprefixbefore", llvm::cl::value_desc("dir"),
llvm::cl::Prefix,
llvm::cl::desc("Set directory to include search path with prefix"));
static llvm::cl::opt<std::string>
isysroot("isysroot", llvm::cl::value_desc("dir"), llvm::cl::init("/"),
llvm::cl::desc("Set the system root directory (usually /)"));
// Finally, implement the code that groks the options above.
// Add the clang headers, which are relative to the clang binary.
@ -478,110 +429,6 @@ std::string GetBuiltinIncludePath(const char *Argv0) {
return P.str();
}
/// InitializeIncludePaths - Process the -I options and set them in the
/// HeaderSearch object.
static void InitializeIncludePaths(HeaderSearchOptions &Opts,
const char *Argv0,
const LangOptions &Lang) {
Opts.Sysroot = isysroot;
Opts.Verbose = Verbose;
// Handle -I... and -F... options, walking the lists in parallel.
unsigned Iidx = 0, Fidx = 0;
while (Iidx < I_dirs.size() && Fidx < F_dirs.size()) {
if (I_dirs.getPosition(Iidx) < F_dirs.getPosition(Fidx)) {
Opts.AddPath(I_dirs[Iidx], frontend::Angled, false, true, false);
++Iidx;
} else {
Opts.AddPath(F_dirs[Fidx], frontend::Angled, false, true, true);
++Fidx;
}
}
// Consume what's left from whatever list was longer.
for (; Iidx != I_dirs.size(); ++Iidx)
Opts.AddPath(I_dirs[Iidx], frontend::Angled, false, true, false);
for (; Fidx != F_dirs.size(); ++Fidx)
Opts.AddPath(F_dirs[Fidx], frontend::Angled, false, true, true);
// Handle -idirafter... options.
for (unsigned i = 0, e = idirafter_dirs.size(); i != e; ++i)
Opts.AddPath(idirafter_dirs[i], frontend::After,
false, true, false);
// Handle -iquote... options.
for (unsigned i = 0, e = iquote_dirs.size(); i != e; ++i)
Opts.AddPath(iquote_dirs[i], frontend::Quoted, false, true, false);
// Handle -isystem... options.
for (unsigned i = 0, e = isystem_dirs.size(); i != e; ++i)
Opts.AddPath(isystem_dirs[i], frontend::System, false, true, false);
// Walk the -iprefix/-iwithprefix/-iwithprefixbefore argument lists in
// parallel, processing the values in order of occurance to get the right
// prefixes.
{
std::string Prefix = ""; // FIXME: this isn't the correct default prefix.
unsigned iprefix_idx = 0;
unsigned iwithprefix_idx = 0;
unsigned iwithprefixbefore_idx = 0;
bool iprefix_done = iprefix_vals.empty();
bool iwithprefix_done = iwithprefix_vals.empty();
bool iwithprefixbefore_done = iwithprefixbefore_vals.empty();
while (!iprefix_done || !iwithprefix_done || !iwithprefixbefore_done) {
if (!iprefix_done &&
(iwithprefix_done ||
iprefix_vals.getPosition(iprefix_idx) <
iwithprefix_vals.getPosition(iwithprefix_idx)) &&
(iwithprefixbefore_done ||
iprefix_vals.getPosition(iprefix_idx) <
iwithprefixbefore_vals.getPosition(iwithprefixbefore_idx))) {
Prefix = iprefix_vals[iprefix_idx];
++iprefix_idx;
iprefix_done = iprefix_idx == iprefix_vals.size();
} else if (!iwithprefix_done &&
(iwithprefixbefore_done ||
iwithprefix_vals.getPosition(iwithprefix_idx) <
iwithprefixbefore_vals.getPosition(iwithprefixbefore_idx))) {
Opts.AddPath(Prefix+iwithprefix_vals[iwithprefix_idx],
frontend::System, false, false, false);
++iwithprefix_idx;
iwithprefix_done = iwithprefix_idx == iwithprefix_vals.size();
} else {
Opts.AddPath(Prefix+iwithprefixbefore_vals[iwithprefixbefore_idx],
frontend::Angled, false, false, false);
++iwithprefixbefore_idx;
iwithprefixbefore_done =
iwithprefixbefore_idx == iwithprefixbefore_vals.size();
}
}
}
// Add CPATH environment paths.
if (const char *Env = getenv("CPATH"))
Opts.EnvIncPath = Env;
// Add language specific environment paths.
if (Lang.CPlusPlus && Lang.ObjC1) {
if (const char *Env = getenv("OBJCPLUS_INCLUDE_PATH"))
Opts.LangEnvIncPath = Env;
} else if (Lang.CPlusPlus) {
if (const char *Env = getenv("CPLUS_INCLUDE_PATH"))
Opts.LangEnvIncPath = Env;
} else if (Lang.ObjC1) {
if (const char *Env = getenv("OBJC_INCLUDE_PATH"))
Opts.LangEnvIncPath = Env;
} else {
if (const char *Env = getenv("C_INCLUDE_PATH"))
Opts.LangEnvIncPath = Env;
}
if (!nobuiltininc)
Opts.BuiltinIncludePath = GetBuiltinIncludePath(Argv0);
Opts.UseStandardIncludes = !nostdinc;
}
//===----------------------------------------------------------------------===//
// Preprocessor construction
//===----------------------------------------------------------------------===//
@ -985,20 +832,21 @@ static void ProcessInputFile(const CompilerInvocation &CompOpts,
ReadAnalyzerOptions()));
break;
case GeneratePCH:
if (RelocatablePCH.getValue() && !isysroot.getNumOccurrences()) {
case GeneratePCH: {
const std::string &Sysroot = CompOpts.getHeaderSearchOpts().Sysroot;
if (RelocatablePCH.getValue() && Sysroot.empty()) {
PP.Diag(SourceLocation(), diag::err_relocatable_without_without_isysroot);
RelocatablePCH.setValue(false);
}
OS.reset(ComputeOutFile(CompOpts, InFile, 0, true, OutPath));
if (RelocatablePCH.getValue())
Consumer.reset(CreatePCHGenerator(PP, OS.get(), isysroot.c_str()));
Consumer.reset(CreatePCHGenerator(PP, OS.get(), Sysroot.c_str()));
else
Consumer.reset(CreatePCHGenerator(PP, OS.get()));
CompleteTranslationUnit = false;
break;
}
case DumpRawTokens: {
llvm::TimeRegion Timer(ClangFrontendTimer);
SourceManager &SM = PP.getSourceManager();
@ -1130,9 +978,9 @@ static void ProcessInputFile(const CompilerInvocation &CompOpts,
if (!ImplicitPCHInclude.empty()) {
// If the user specified -isysroot, it will be used for relocatable PCH
// files.
const char *isysrootPCH = 0;
if (isysroot.getNumOccurrences() != 0)
isysrootPCH = isysroot.c_str();
const char *isysrootPCH = CompOpts.getHeaderSearchOpts().Sysroot.c_str();
if (isysrootPCH[0] == '\0')
isysrootPCH = 0;
Reader.reset(new PCHReader(PP, ContextOwner.get(), isysrootPCH));
@ -1436,7 +1284,10 @@ static void ConstructCompilerInvocation(CompilerInvocation &Opts,
Opts.getCompileOpts(), Opts.getTargetFeatures());
// Initialize the header search options.
InitializeIncludePaths(Opts.getHeaderSearchOpts(), Argv0, Opts.getLangOpts());
InitializeHeaderSearchOptions(Opts.getHeaderSearchOpts(),
GetBuiltinIncludePath(Argv0),
Verbose,
Opts.getLangOpts());
// Initialize the other preprocessor options.
InitializePreprocessorOptions(Opts.getPreprocessorOpts());