2016-01-11 00:18:09 +08:00
|
|
|
//===--- CompilerInvocation.cpp -------------------------------------------===//
|
2009-11-17 14:02:29 +08:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2015-11-04 02:33:07 +08:00
|
|
|
#include "TestModuleFileExtension.h"
|
2016-01-06 22:35:46 +08:00
|
|
|
#include "clang/Basic/Builtins.h"
|
2010-11-04 06:45:23 +08:00
|
|
|
#include "clang/Basic/FileManager.h"
|
2012-12-04 17:13:33 +08:00
|
|
|
#include "clang/Basic/Version.h"
|
2014-12-29 20:09:08 +08:00
|
|
|
#include "clang/Config/config.h"
|
2009-12-01 11:16:53 +08:00
|
|
|
#include "clang/Driver/DriverDiagnostic.h"
|
2012-12-04 17:13:33 +08:00
|
|
|
#include "clang/Driver/Options.h"
|
2013-06-15 01:17:23 +08:00
|
|
|
#include "clang/Driver/Util.h"
|
2016-01-06 22:35:46 +08:00
|
|
|
#include "clang/Frontend/CompilerInvocation.h"
|
2014-04-16 02:16:25 +08:00
|
|
|
#include "clang/Frontend/FrontendDiagnostic.h"
|
2009-12-01 11:16:53 +08:00
|
|
|
#include "clang/Frontend/LangStandard.h"
|
2013-06-15 01:17:23 +08:00
|
|
|
#include "clang/Frontend/Utils.h"
|
2012-12-04 17:13:33 +08:00
|
|
|
#include "clang/Lex/HeaderSearchOptions.h"
|
2010-08-19 07:57:17 +08:00
|
|
|
#include "clang/Serialization/ASTReader.h"
|
2015-11-04 02:33:07 +08:00
|
|
|
#include "clang/Serialization/ModuleFileExtension.h"
|
2012-11-06 03:45:09 +08:00
|
|
|
#include "llvm/ADT/Hashing.h"
|
2014-06-21 06:58:35 +08:00
|
|
|
#include "llvm/ADT/STLExtras.h"
|
2015-01-14 19:29:14 +08:00
|
|
|
#include "llvm/ADT/SmallVector.h"
|
2009-11-17 14:02:29 +08:00
|
|
|
#include "llvm/ADT/StringExtras.h"
|
2009-12-01 11:16:53 +08:00
|
|
|
#include "llvm/ADT/StringSwitch.h"
|
2010-08-30 17:42:39 +08:00
|
|
|
#include "llvm/ADT/Triple.h"
|
2015-10-28 01:56:59 +08:00
|
|
|
#include "llvm/Linker/Linker.h"
|
2013-06-15 01:17:23 +08:00
|
|
|
#include "llvm/Option/Arg.h"
|
|
|
|
#include "llvm/Option/ArgList.h"
|
|
|
|
#include "llvm/Option/OptTable.h"
|
|
|
|
#include "llvm/Option/Option.h"
|
2016-03-03 04:59:36 +08:00
|
|
|
#include "llvm/ProfileData/InstrProfReader.h"
|
2014-05-08 10:28:32 +08:00
|
|
|
#include "llvm/Support/CodeGen.h"
|
2009-11-17 14:02:29 +08:00
|
|
|
#include "llvm/Support/ErrorHandling.h"
|
2013-06-26 13:03:40 +08:00
|
|
|
#include "llvm/Support/FileSystem.h"
|
2010-11-30 02:12:39 +08:00
|
|
|
#include "llvm/Support/Host.h"
|
|
|
|
#include "llvm/Support/Path.h"
|
2013-09-11 08:38:02 +08:00
|
|
|
#include "llvm/Support/Process.h"
|
2015-11-09 20:40:41 +08:00
|
|
|
#include "llvm/Target/TargetOptions.h"
|
2014-03-03 01:08:31 +08:00
|
|
|
#include <atomic>
|
2014-03-09 19:36:40 +08:00
|
|
|
#include <memory>
|
2013-05-11 05:54:08 +08:00
|
|
|
#include <sys/stat.h>
|
2014-06-13 01:19:42 +08:00
|
|
|
#include <system_error>
|
2009-11-17 14:02:29 +08:00
|
|
|
using namespace clang;
|
|
|
|
|
2011-11-18 07:01:24 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Initialization.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2011-11-18 12:32:13 +08:00
|
|
|
CompilerInvocationBase::CompilerInvocationBase()
|
2012-10-24 06:26:28 +08:00
|
|
|
: LangOpts(new LangOptions()), TargetOpts(new TargetOptions()),
|
2012-10-25 00:19:39 +08:00
|
|
|
DiagnosticOpts(new DiagnosticOptions()),
|
2012-10-25 01:01:35 +08:00
|
|
|
HeaderSearchOpts(new HeaderSearchOptions()),
|
|
|
|
PreprocessorOpts(new PreprocessorOptions()) {}
|
2011-11-18 07:01:24 +08:00
|
|
|
|
2011-11-18 12:32:13 +08:00
|
|
|
CompilerInvocationBase::CompilerInvocationBase(const CompilerInvocationBase &X)
|
2012-02-20 22:00:23 +08:00
|
|
|
: RefCountedBase<CompilerInvocation>(),
|
2015-08-05 23:08:53 +08:00
|
|
|
LangOpts(new LangOptions(*X.getLangOpts())),
|
2012-10-24 06:26:28 +08:00
|
|
|
TargetOpts(new TargetOptions(X.getTargetOpts())),
|
2012-10-25 00:19:39 +08:00
|
|
|
DiagnosticOpts(new DiagnosticOptions(X.getDiagnosticOpts())),
|
2012-10-25 01:01:35 +08:00
|
|
|
HeaderSearchOpts(new HeaderSearchOptions(X.getHeaderSearchOpts())),
|
|
|
|
PreprocessorOpts(new PreprocessorOptions(X.getPreprocessorOpts())) {}
|
2011-11-18 07:01:24 +08:00
|
|
|
|
2015-10-20 21:23:58 +08:00
|
|
|
CompilerInvocationBase::~CompilerInvocationBase() {}
|
2014-05-12 06:10:52 +08:00
|
|
|
|
2011-11-18 07:01:24 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
2012-11-01 11:48:49 +08:00
|
|
|
// Deserialization (from args)
|
2009-12-01 11:16:53 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
using namespace clang::driver;
|
2012-05-01 22:57:16 +08:00
|
|
|
using namespace clang::driver::options;
|
2013-06-15 01:17:23 +08:00
|
|
|
using namespace llvm::opt;
|
2009-12-01 11:16:53 +08:00
|
|
|
|
|
|
|
//
|
|
|
|
|
2010-12-04 09:50:36 +08:00
|
|
|
static unsigned getOptimizationLevel(ArgList &Args, InputKind IK,
|
2011-09-26 07:23:43 +08:00
|
|
|
DiagnosticsEngine &Diags) {
|
2010-12-04 09:50:45 +08:00
|
|
|
unsigned DefaultOpt = 0;
|
|
|
|
if (IK == IK_OpenCL && !Args.hasArg(OPT_cl_opt_disable))
|
|
|
|
DefaultOpt = 2;
|
2012-05-01 22:57:16 +08:00
|
|
|
|
|
|
|
if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
|
|
|
|
if (A->getOption().matches(options::OPT_O0))
|
|
|
|
return 0;
|
|
|
|
|
2013-04-11 05:26:02 +08:00
|
|
|
if (A->getOption().matches(options::OPT_Ofast))
|
|
|
|
return 3;
|
|
|
|
|
2012-05-01 22:57:16 +08:00
|
|
|
assert (A->getOption().matches(options::OPT_O));
|
|
|
|
|
2013-01-13 03:30:44 +08:00
|
|
|
StringRef S(A->getValue());
|
2012-05-01 22:57:16 +08:00
|
|
|
if (S == "s" || S == "z" || S.empty())
|
|
|
|
return 2;
|
|
|
|
|
2013-06-15 01:17:23 +08:00
|
|
|
return getLastArgIntValue(Args, OPT_O, DefaultOpt, Diags);
|
2012-05-01 22:57:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return DefaultOpt;
|
|
|
|
}
|
|
|
|
|
2013-04-11 05:30:03 +08:00
|
|
|
static unsigned getOptimizationLevelSize(ArgList &Args) {
|
2012-05-01 22:57:16 +08:00
|
|
|
if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
|
|
|
|
if (A->getOption().matches(options::OPT_O)) {
|
2012-11-01 12:30:05 +08:00
|
|
|
switch (A->getValue()[0]) {
|
2012-05-01 22:57:16 +08:00
|
|
|
default:
|
|
|
|
return 0;
|
|
|
|
case 's':
|
|
|
|
return 1;
|
|
|
|
case 'z':
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
Use -Rblah, not -Wblah, to control remark diagnostics. This was always the
intent when we added remark support, but was never implemented in the general
case, because the first -R flags didn't need it. (-Rpass= had special handling
to accomodate its argument.)
-Rno-foo, -Reverything, and -Rno-everything can be used to turn off a remark,
or to turn on or off all remarks. Per discussion on cfe-commits, -Weverything
does not affect remarks, and -Reverything does not affect warnings or errors.
The only "real" -R flag we have right now is -Rmodule-build; that flag is
effectively renamed from -Wmodule-build to -Rmodule-build by this change.
-Wpass and -Wno-pass (and their friends) are also renamed to -Rpass and
-Rno-pass by this change; it's not completely clear whether we intended to have
a -Rpass (with no =pattern), but that is unchanged by this commit, other than
the flag name. The default pattern is effectively one which matches no passes.
In future, we may want to make the default pattern be .*, so that -Reverything
works for -Rpass properly.
llvm-svn: 215046
2014-08-07 08:24:21 +08:00
|
|
|
static void addDiagnosticArgs(ArgList &Args, OptSpecifier Group,
|
|
|
|
OptSpecifier GroupWithValue,
|
|
|
|
std::vector<std::string> &Diagnostics) {
|
|
|
|
for (Arg *A : Args.filtered(Group)) {
|
2012-05-01 22:57:16 +08:00
|
|
|
if (A->getOption().getKind() == Option::FlagClass) {
|
Use -Rblah, not -Wblah, to control remark diagnostics. This was always the
intent when we added remark support, but was never implemented in the general
case, because the first -R flags didn't need it. (-Rpass= had special handling
to accomodate its argument.)
-Rno-foo, -Reverything, and -Rno-everything can be used to turn off a remark,
or to turn on or off all remarks. Per discussion on cfe-commits, -Weverything
does not affect remarks, and -Reverything does not affect warnings or errors.
The only "real" -R flag we have right now is -Rmodule-build; that flag is
effectively renamed from -Wmodule-build to -Rmodule-build by this change.
-Wpass and -Wno-pass (and their friends) are also renamed to -Rpass and
-Rno-pass by this change; it's not completely clear whether we intended to have
a -Rpass (with no =pattern), but that is unchanged by this commit, other than
the flag name. The default pattern is effectively one which matches no passes.
In future, we may want to make the default pattern be .*, so that -Reverything
works for -Rpass properly.
llvm-svn: 215046
2014-08-07 08:24:21 +08:00
|
|
|
// The argument is a pure flag (such as OPT_Wall or OPT_Wdeprecated). Add
|
|
|
|
// its name (minus the "W" or "R" at the beginning) to the warning list.
|
|
|
|
Diagnostics.push_back(A->getOption().getName().drop_front(1));
|
|
|
|
} else if (A->getOption().matches(GroupWithValue)) {
|
|
|
|
// This is -Wfoo= or -Rfoo=, where foo is the name of the diagnostic group.
|
|
|
|
Diagnostics.push_back(A->getOption().getName().drop_front(1).rtrim("=-"));
|
2012-05-01 22:57:16 +08:00
|
|
|
} else {
|
Use -Rblah, not -Wblah, to control remark diagnostics. This was always the
intent when we added remark support, but was never implemented in the general
case, because the first -R flags didn't need it. (-Rpass= had special handling
to accomodate its argument.)
-Rno-foo, -Reverything, and -Rno-everything can be used to turn off a remark,
or to turn on or off all remarks. Per discussion on cfe-commits, -Weverything
does not affect remarks, and -Reverything does not affect warnings or errors.
The only "real" -R flag we have right now is -Rmodule-build; that flag is
effectively renamed from -Wmodule-build to -Rmodule-build by this change.
-Wpass and -Wno-pass (and their friends) are also renamed to -Rpass and
-Rno-pass by this change; it's not completely clear whether we intended to have
a -Rpass (with no =pattern), but that is unchanged by this commit, other than
the flag name. The default pattern is effectively one which matches no passes.
In future, we may want to make the default pattern be .*, so that -Reverything
works for -Rpass properly.
llvm-svn: 215046
2014-08-07 08:24:21 +08:00
|
|
|
// Otherwise, add its value (for OPT_W_Joined and similar).
|
|
|
|
for (const char *Arg : A->getValues())
|
2015-05-30 03:42:19 +08:00
|
|
|
Diagnostics.emplace_back(Arg);
|
2012-05-01 22:57:16 +08:00
|
|
|
}
|
|
|
|
}
|
2010-12-04 09:50:36 +08:00
|
|
|
}
|
|
|
|
|
2016-01-06 22:35:46 +08:00
|
|
|
static void getAllNoBuiltinFuncValues(ArgList &Args,
|
|
|
|
std::vector<std::string> &Funcs) {
|
|
|
|
SmallVector<const char *, 8> Values;
|
|
|
|
for (const auto &Arg : Args) {
|
|
|
|
const Option &O = Arg->getOption();
|
|
|
|
if (O.matches(options::OPT_fno_builtin_)) {
|
|
|
|
const char *FuncName = Arg->getValue();
|
|
|
|
if (Builtin::Context::isBuiltinFunc(FuncName))
|
|
|
|
Values.push_back(FuncName);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Funcs.insert(Funcs.end(), Values.begin(), Values.end());
|
|
|
|
}
|
|
|
|
|
2011-12-23 11:05:38 +08:00
|
|
|
static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
|
2011-09-26 07:23:43 +08:00
|
|
|
DiagnosticsEngine &Diags) {
|
2012-05-01 22:57:16 +08:00
|
|
|
using namespace options;
|
2011-12-23 11:05:38 +08:00
|
|
|
bool Success = true;
|
2009-12-01 11:16:53 +08:00
|
|
|
if (Arg *A = Args.getLastArg(OPT_analyzer_store)) {
|
2012-11-01 12:30:05 +08:00
|
|
|
StringRef Name = A->getValue();
|
2009-12-01 11:16:53 +08:00
|
|
|
AnalysisStores Value = llvm::StringSwitch<AnalysisStores>(Name)
|
|
|
|
#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN) \
|
|
|
|
.Case(CMDFLAG, NAME##Model)
|
2012-08-31 12:35:58 +08:00
|
|
|
#include "clang/StaticAnalyzer/Core/Analyses.def"
|
2009-12-01 11:16:53 +08:00
|
|
|
.Default(NumStores);
|
2011-12-23 11:05:38 +08:00
|
|
|
if (Value == NumStores) {
|
2009-12-01 11:16:53 +08:00
|
|
|
Diags.Report(diag::err_drv_invalid_value)
|
2010-06-10 06:30:54 +08:00
|
|
|
<< A->getAsString(Args) << Name;
|
2011-12-23 11:05:38 +08:00
|
|
|
Success = false;
|
|
|
|
} else {
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.AnalysisStoreOpt = Value;
|
2011-12-23 11:05:38 +08:00
|
|
|
}
|
2009-12-01 11:16:53 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (Arg *A = Args.getLastArg(OPT_analyzer_constraints)) {
|
2012-11-01 12:30:05 +08:00
|
|
|
StringRef Name = A->getValue();
|
2009-12-01 11:16:53 +08:00
|
|
|
AnalysisConstraints Value = llvm::StringSwitch<AnalysisConstraints>(Name)
|
|
|
|
#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN) \
|
|
|
|
.Case(CMDFLAG, NAME##Model)
|
2012-08-31 12:35:58 +08:00
|
|
|
#include "clang/StaticAnalyzer/Core/Analyses.def"
|
2009-12-01 11:16:53 +08:00
|
|
|
.Default(NumConstraints);
|
2011-12-23 11:05:38 +08:00
|
|
|
if (Value == NumConstraints) {
|
2009-12-01 11:16:53 +08:00
|
|
|
Diags.Report(diag::err_drv_invalid_value)
|
2010-06-10 06:30:54 +08:00
|
|
|
<< A->getAsString(Args) << Name;
|
2011-12-23 11:05:38 +08:00
|
|
|
Success = false;
|
|
|
|
} else {
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.AnalysisConstraintsOpt = Value;
|
2011-12-23 11:05:38 +08:00
|
|
|
}
|
2009-12-01 11:16:53 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (Arg *A = Args.getLastArg(OPT_analyzer_output)) {
|
2012-11-01 12:30:05 +08:00
|
|
|
StringRef Name = A->getValue();
|
2009-12-01 11:16:53 +08:00
|
|
|
AnalysisDiagClients Value = llvm::StringSwitch<AnalysisDiagClients>(Name)
|
2013-08-16 09:06:30 +08:00
|
|
|
#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN) \
|
2009-12-01 11:16:53 +08:00
|
|
|
.Case(CMDFLAG, PD_##NAME)
|
2012-08-31 12:35:58 +08:00
|
|
|
#include "clang/StaticAnalyzer/Core/Analyses.def"
|
2009-12-01 11:16:53 +08:00
|
|
|
.Default(NUM_ANALYSIS_DIAG_CLIENTS);
|
2011-12-23 11:05:38 +08:00
|
|
|
if (Value == NUM_ANALYSIS_DIAG_CLIENTS) {
|
2009-12-01 11:16:53 +08:00
|
|
|
Diags.Report(diag::err_drv_invalid_value)
|
2010-06-10 06:30:54 +08:00
|
|
|
<< A->getAsString(Args) << Name;
|
2011-12-23 11:05:38 +08:00
|
|
|
Success = false;
|
|
|
|
} else {
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.AnalysisDiagOpt = Value;
|
2011-12-23 11:05:38 +08:00
|
|
|
}
|
2009-12-01 11:16:53 +08:00
|
|
|
}
|
|
|
|
|
2011-09-30 10:03:00 +08:00
|
|
|
if (Arg *A = Args.getLastArg(OPT_analyzer_purge)) {
|
2012-11-01 12:30:05 +08:00
|
|
|
StringRef Name = A->getValue();
|
2011-09-30 10:03:00 +08:00
|
|
|
AnalysisPurgeMode Value = llvm::StringSwitch<AnalysisPurgeMode>(Name)
|
|
|
|
#define ANALYSIS_PURGE(NAME, CMDFLAG, DESC) \
|
|
|
|
.Case(CMDFLAG, NAME)
|
2012-08-31 12:35:58 +08:00
|
|
|
#include "clang/StaticAnalyzer/Core/Analyses.def"
|
2011-09-30 10:03:00 +08:00
|
|
|
.Default(NumPurgeModes);
|
2011-12-23 11:05:38 +08:00
|
|
|
if (Value == NumPurgeModes) {
|
2011-09-30 10:03:00 +08:00
|
|
|
Diags.Report(diag::err_drv_invalid_value)
|
|
|
|
<< A->getAsString(Args) << Name;
|
2011-12-23 11:05:38 +08:00
|
|
|
Success = false;
|
|
|
|
} else {
|
2011-09-30 10:03:00 +08:00
|
|
|
Opts.AnalysisPurgeOpt = Value;
|
2011-12-23 11:05:38 +08:00
|
|
|
}
|
2011-09-30 10:03:00 +08:00
|
|
|
}
|
|
|
|
|
2012-03-09 07:16:35 +08:00
|
|
|
if (Arg *A = Args.getLastArg(OPT_analyzer_inlining_mode)) {
|
2012-11-01 12:30:05 +08:00
|
|
|
StringRef Name = A->getValue();
|
2012-03-09 07:16:35 +08:00
|
|
|
AnalysisInliningMode Value = llvm::StringSwitch<AnalysisInliningMode>(Name)
|
|
|
|
#define ANALYSIS_INLINING_MODE(NAME, CMDFLAG, DESC) \
|
|
|
|
.Case(CMDFLAG, NAME)
|
2012-08-31 12:35:58 +08:00
|
|
|
#include "clang/StaticAnalyzer/Core/Analyses.def"
|
2012-03-09 07:16:35 +08:00
|
|
|
.Default(NumInliningModes);
|
|
|
|
if (Value == NumInliningModes) {
|
|
|
|
Diags.Report(diag::err_drv_invalid_value)
|
|
|
|
<< A->getAsString(Args) << Name;
|
|
|
|
Success = false;
|
|
|
|
} else {
|
|
|
|
Opts.InliningMode = Value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-02-25 08:09:51 +08:00
|
|
|
Opts.ShowCheckerHelp = Args.hasArg(OPT_analyzer_checker_help);
|
2014-08-30 04:01:38 +08:00
|
|
|
Opts.DisableAllChecks = Args.hasArg(OPT_analyzer_disable_all_checks);
|
|
|
|
|
2012-08-31 03:26:53 +08:00
|
|
|
Opts.visualizeExplodedGraphWithGraphViz =
|
|
|
|
Args.hasArg(OPT_analyzer_viz_egraph_graphviz);
|
|
|
|
Opts.visualizeExplodedGraphWithUbiGraph =
|
|
|
|
Args.hasArg(OPT_analyzer_viz_egraph_ubigraph);
|
2012-03-29 03:59:16 +08:00
|
|
|
Opts.NoRetryExhausted = Args.hasArg(OPT_analyzer_disable_retry_exhausted);
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.AnalyzeAll = Args.hasArg(OPT_analyzer_opt_analyze_headers);
|
|
|
|
Opts.AnalyzerDisplayProgress = Args.hasArg(OPT_analyzer_display_progress);
|
2009-12-08 06:06:12 +08:00
|
|
|
Opts.AnalyzeNestedBlocks =
|
|
|
|
Args.hasArg(OPT_analyzer_opt_analyze_nested_blocks);
|
2012-08-31 03:26:48 +08:00
|
|
|
Opts.eagerlyAssumeBinOpBifurcation = Args.hasArg(OPT_analyzer_eagerly_assume);
|
2010-05-21 00:54:55 +08:00
|
|
|
Opts.AnalyzeSpecificFunction = Args.getLastArgValue(OPT_analyze_function);
|
2010-08-03 08:09:51 +08:00
|
|
|
Opts.UnoptimizedCFG = Args.hasArg(OPT_analysis_UnoptimizedCFG);
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.TrimGraph = Args.hasArg(OPT_trim_egraph);
|
2013-06-15 01:17:23 +08:00
|
|
|
Opts.maxBlockVisitOnPath =
|
|
|
|
getLastArgIntValue(Args, OPT_analyzer_max_loop, 4, Diags);
|
2012-02-28 05:33:16 +08:00
|
|
|
Opts.PrintStats = Args.hasArg(OPT_analyzer_stats);
|
2012-03-03 03:05:03 +08:00
|
|
|
Opts.InlineMaxStackDepth =
|
2013-06-15 01:17:23 +08:00
|
|
|
getLastArgIntValue(Args, OPT_analyzer_inline_max_stack_depth,
|
|
|
|
Opts.InlineMaxStackDepth, Diags);
|
2011-02-15 02:13:31 +08:00
|
|
|
|
|
|
|
Opts.CheckersControlList.clear();
|
2015-06-09 09:57:17 +08:00
|
|
|
for (const Arg *A :
|
|
|
|
Args.filtered(OPT_analyzer_checker, OPT_analyzer_disable_checker)) {
|
2011-02-15 02:13:31 +08:00
|
|
|
A->claim();
|
|
|
|
bool enable = (A->getOption().getID() == OPT_analyzer_checker);
|
2011-02-24 16:42:20 +08:00
|
|
|
// We can have a list of comma separated checker names, e.g:
|
|
|
|
// '-analyzer-checker=cocoa,unix'
|
2012-11-01 12:30:05 +08:00
|
|
|
StringRef checkerList = A->getValue();
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<StringRef, 4> checkers;
|
2011-02-24 16:42:20 +08:00
|
|
|
checkerList.split(checkers, ",");
|
2015-05-30 03:42:19 +08:00
|
|
|
for (StringRef checker : checkers)
|
|
|
|
Opts.CheckersControlList.emplace_back(checker, enable);
|
2011-02-15 02:13:31 +08:00
|
|
|
}
|
2015-02-25 05:45:33 +08:00
|
|
|
|
2012-08-29 13:55:00 +08:00
|
|
|
// Go through the analyzer configuration options.
|
2015-06-09 09:57:17 +08:00
|
|
|
for (const Arg *A : Args.filtered(OPT_analyzer_config)) {
|
2012-08-29 13:55:00 +08:00
|
|
|
A->claim();
|
|
|
|
// We can have a list of comma separated config names, e.g:
|
2012-08-30 13:49:16 +08:00
|
|
|
// '-analyzer-config key1=val1,key2=val2'
|
2012-11-01 12:30:05 +08:00
|
|
|
StringRef configList = A->getValue();
|
2012-08-29 13:55:00 +08:00
|
|
|
SmallVector<StringRef, 4> configVals;
|
|
|
|
configList.split(configVals, ",");
|
|
|
|
for (unsigned i = 0, e = configVals.size(); i != e; ++i) {
|
|
|
|
StringRef key, val;
|
2014-03-02 21:01:17 +08:00
|
|
|
std::tie(key, val) = configVals[i].split("=");
|
2012-08-29 13:55:00 +08:00
|
|
|
if (val.empty()) {
|
|
|
|
Diags.Report(SourceLocation(),
|
|
|
|
diag::err_analyzer_config_no_value) << configVals[i];
|
|
|
|
Success = false;
|
|
|
|
break;
|
|
|
|
}
|
2012-08-30 13:49:16 +08:00
|
|
|
if (val.find('=') != StringRef::npos) {
|
2012-08-29 13:55:00 +08:00
|
|
|
Diags.Report(SourceLocation(),
|
|
|
|
diag::err_analyzer_config_multiple_values)
|
|
|
|
<< configVals[i];
|
|
|
|
Success = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
Opts.Config[key] = val;
|
|
|
|
}
|
|
|
|
}
|
2011-12-23 11:05:38 +08:00
|
|
|
|
|
|
|
return Success;
|
2009-12-01 11:16:53 +08:00
|
|
|
}
|
|
|
|
|
2012-01-25 08:20:29 +08:00
|
|
|
static bool ParseMigratorArgs(MigratorOptions &Opts, ArgList &Args) {
|
|
|
|
Opts.NoNSAllocReallocError = Args.hasArg(OPT_migrator_no_nsalloc_error);
|
2012-01-27 04:57:58 +08:00
|
|
|
Opts.NoFinalizeRemoval = Args.hasArg(OPT_migrator_no_finalize_removal);
|
2012-01-25 08:20:29 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-02-22 22:21:27 +08:00
|
|
|
static void ParseCommentArgs(CommentOptions &Opts, ArgList &Args) {
|
|
|
|
Opts.BlockCommandNames = Args.getAllArgValues(OPT_fcomment_block_commands);
|
2013-04-10 23:35:17 +08:00
|
|
|
Opts.ParseAllComments = Args.hasArg(OPT_fparse_all_comments);
|
2013-02-22 22:21:27 +08:00
|
|
|
}
|
|
|
|
|
2014-05-08 10:28:32 +08:00
|
|
|
static StringRef getCodeModel(ArgList &Args, DiagnosticsEngine &Diags) {
|
|
|
|
if (Arg *A = Args.getLastArg(OPT_mcode_model)) {
|
|
|
|
StringRef Value = A->getValue();
|
|
|
|
if (Value == "small" || Value == "kernel" || Value == "medium" ||
|
|
|
|
Value == "large")
|
|
|
|
return Value;
|
|
|
|
Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Value;
|
|
|
|
}
|
|
|
|
return "default";
|
|
|
|
}
|
|
|
|
|
2014-05-30 03:55:06 +08:00
|
|
|
/// \brief Create a new Regex instance out of the string value in \p RpassArg.
|
|
|
|
/// It returns a pointer to the newly generated Regex instance.
|
|
|
|
static std::shared_ptr<llvm::Regex>
|
|
|
|
GenerateOptimizationRemarkRegex(DiagnosticsEngine &Diags, ArgList &Args,
|
|
|
|
Arg *RpassArg) {
|
|
|
|
StringRef Val = RpassArg->getValue();
|
|
|
|
std::string RegexError;
|
|
|
|
std::shared_ptr<llvm::Regex> Pattern = std::make_shared<llvm::Regex>(Val);
|
|
|
|
if (!Pattern->isValid(RegexError)) {
|
|
|
|
Diags.Report(diag::err_drv_optimization_remark_pattern)
|
|
|
|
<< RegexError << RpassArg->getAsString(Args);
|
|
|
|
Pattern.reset();
|
|
|
|
}
|
|
|
|
return Pattern;
|
|
|
|
}
|
|
|
|
|
2015-06-13 15:11:40 +08:00
|
|
|
static bool parseDiagnosticLevelMask(StringRef FlagName,
|
|
|
|
const std::vector<std::string> &Levels,
|
|
|
|
DiagnosticsEngine *Diags,
|
|
|
|
DiagnosticLevelMask &M) {
|
|
|
|
bool Success = true;
|
|
|
|
for (const auto &Level : Levels) {
|
|
|
|
DiagnosticLevelMask const PM =
|
|
|
|
llvm::StringSwitch<DiagnosticLevelMask>(Level)
|
|
|
|
.Case("note", DiagnosticLevelMask::Note)
|
|
|
|
.Case("remark", DiagnosticLevelMask::Remark)
|
|
|
|
.Case("warning", DiagnosticLevelMask::Warning)
|
|
|
|
.Case("error", DiagnosticLevelMask::Error)
|
|
|
|
.Default(DiagnosticLevelMask::None);
|
|
|
|
if (PM == DiagnosticLevelMask::None) {
|
|
|
|
Success = false;
|
|
|
|
if (Diags)
|
|
|
|
Diags->Report(diag::err_drv_invalid_value) << FlagName << Level;
|
|
|
|
}
|
|
|
|
M = M | PM;
|
|
|
|
}
|
|
|
|
return Success;
|
|
|
|
}
|
|
|
|
|
Reimplement -fsanitize-recover family of flags.
Introduce the following -fsanitize-recover flags:
- -fsanitize-recover=<list>: Enable recovery for selected checks or
group of checks. It is forbidden to explicitly list unrecoverable
sanitizers here (that is, "address", "unreachable", "return").
- -fno-sanitize-recover=<list>: Disable recovery for selected checks or
group of checks.
- -f(no-)?sanitize-recover is now a synonym for
-f(no-)?sanitize-recover=undefined,integer and will soon be deprecated.
These flags are parsed left to right, and mask of "recoverable"
sanitizer is updated accordingly, much like what we do for -fsanitize= flags.
-fsanitize= and -fsanitize-recover= flag families are independent.
CodeGen change: If there is a single UBSan handler function, responsible
for implementing multiple checks, which have different recoverable setting,
then we emit two handler calls instead of one:
the first one for the set of "unrecoverable" checks, another one - for
set of "recoverable" checks. If all checks implemented by a handler have the
same recoverability setting, then the generated code will be the same.
llvm-svn: 225719
2015-01-13 06:39:12 +08:00
|
|
|
static void parseSanitizerKinds(StringRef FlagName,
|
|
|
|
const std::vector<std::string> &Sanitizers,
|
|
|
|
DiagnosticsEngine &Diags, SanitizerSet &S) {
|
|
|
|
for (const auto &Sanitizer : Sanitizers) {
|
2015-05-12 05:39:20 +08:00
|
|
|
SanitizerMask K = parseSanitizerValue(Sanitizer, /*AllowGroups=*/false);
|
2015-05-12 05:39:14 +08:00
|
|
|
if (K == 0)
|
Reimplement -fsanitize-recover family of flags.
Introduce the following -fsanitize-recover flags:
- -fsanitize-recover=<list>: Enable recovery for selected checks or
group of checks. It is forbidden to explicitly list unrecoverable
sanitizers here (that is, "address", "unreachable", "return").
- -fno-sanitize-recover=<list>: Disable recovery for selected checks or
group of checks.
- -f(no-)?sanitize-recover is now a synonym for
-f(no-)?sanitize-recover=undefined,integer and will soon be deprecated.
These flags are parsed left to right, and mask of "recoverable"
sanitizer is updated accordingly, much like what we do for -fsanitize= flags.
-fsanitize= and -fsanitize-recover= flag families are independent.
CodeGen change: If there is a single UBSan handler function, responsible
for implementing multiple checks, which have different recoverable setting,
then we emit two handler calls instead of one:
the first one for the set of "unrecoverable" checks, another one - for
set of "recoverable" checks. If all checks implemented by a handler have the
same recoverability setting, then the generated code will be the same.
llvm-svn: 225719
2015-01-13 06:39:12 +08:00
|
|
|
Diags.Report(diag::err_drv_invalid_value) << FlagName << Sanitizer;
|
|
|
|
else
|
|
|
|
S.set(K, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-03 04:59:36 +08:00
|
|
|
// Set the profile kind for fprofile-instrument.
|
|
|
|
static void setPGOInstrumentor(CodeGenOptions &Opts, ArgList &Args,
|
|
|
|
DiagnosticsEngine &Diags) {
|
|
|
|
Arg *A = Args.getLastArg(OPT_fprofile_instrument_EQ);
|
|
|
|
if (A == nullptr)
|
|
|
|
return;
|
|
|
|
StringRef S = A->getValue();
|
|
|
|
unsigned I = llvm::StringSwitch<unsigned>(S)
|
|
|
|
.Case("none", CodeGenOptions::ProfileNone)
|
|
|
|
.Case("clang", CodeGenOptions::ProfileClangInstr)
|
|
|
|
.Case("llvm", CodeGenOptions::ProfileIRInstr)
|
|
|
|
.Default(~0U);
|
|
|
|
if (I == ~0U) {
|
|
|
|
Diags.Report(diag::err_drv_invalid_pgo_instrumentor) << A->getAsString(Args)
|
|
|
|
<< S;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
CodeGenOptions::ProfileInstrKind Instrumentor =
|
|
|
|
static_cast<CodeGenOptions::ProfileInstrKind>(I);
|
|
|
|
Opts.setProfileInstr(Instrumentor);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the profile kind using fprofile-instrument-use-path.
|
|
|
|
static void setPGOUseInstrumentor(CodeGenOptions &Opts,
|
2016-05-29 19:04:56 +08:00
|
|
|
const Twine &ProfileName) {
|
2016-03-03 04:59:36 +08:00
|
|
|
auto ReaderOrErr = llvm::IndexedInstrProfReader::create(ProfileName);
|
|
|
|
// In error, return silently and let Clang PGOUse report the error message.
|
2016-05-19 11:54:54 +08:00
|
|
|
if (auto E = ReaderOrErr.takeError()) {
|
|
|
|
llvm::consumeError(std::move(E));
|
2016-03-03 04:59:36 +08:00
|
|
|
Opts.setProfileUse(CodeGenOptions::ProfileClangInstr);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
std::unique_ptr<llvm::IndexedInstrProfReader> PGOReader =
|
|
|
|
std::move(ReaderOrErr.get());
|
|
|
|
if (PGOReader->isIRLevelProfile())
|
|
|
|
Opts.setProfileUse(CodeGenOptions::ProfileIRInstr);
|
|
|
|
else
|
|
|
|
Opts.setProfileUse(CodeGenOptions::ProfileClangInstr);
|
|
|
|
}
|
|
|
|
|
2011-12-23 11:05:38 +08:00
|
|
|
static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
|
2014-01-07 09:19:08 +08:00
|
|
|
DiagnosticsEngine &Diags,
|
|
|
|
const TargetOptions &TargetOpts) {
|
2012-05-01 22:57:16 +08:00
|
|
|
using namespace options;
|
2011-12-23 11:05:38 +08:00
|
|
|
bool Success = true;
|
2015-12-11 02:52:50 +08:00
|
|
|
llvm::Triple Triple = llvm::Triple(TargetOpts.Triple);
|
2010-12-04 09:50:36 +08:00
|
|
|
|
2014-12-17 05:57:03 +08:00
|
|
|
unsigned OptimizationLevel = getOptimizationLevel(Args, IK, Diags);
|
2013-11-18 21:23:07 +08:00
|
|
|
// TODO: This could be done in Driver
|
|
|
|
unsigned MaxOptLevel = 3;
|
2014-12-17 05:57:03 +08:00
|
|
|
if (OptimizationLevel > MaxOptLevel) {
|
|
|
|
// If the optimization level is not supported, fall back on the default
|
|
|
|
// optimization
|
2013-11-18 21:23:07 +08:00
|
|
|
Diags.Report(diag::warn_drv_optimization_value)
|
|
|
|
<< Args.getLastArg(OPT_O)->getAsString(Args) << "-O" << MaxOptLevel;
|
2014-12-17 05:57:03 +08:00
|
|
|
OptimizationLevel = MaxOptLevel;
|
2009-12-01 11:16:53 +08:00
|
|
|
}
|
2014-12-17 05:57:03 +08:00
|
|
|
Opts.OptimizationLevel = OptimizationLevel;
|
2009-12-01 11:16:53 +08:00
|
|
|
|
|
|
|
// We must always run at least the always inlining pass.
|
2012-10-24 04:05:01 +08:00
|
|
|
Opts.setInlining(
|
|
|
|
(Opts.OptimizationLevel > 1) ? CodeGenOptions::NormalInlining
|
|
|
|
: CodeGenOptions::OnlyAlwaysInlining);
|
2012-03-07 05:17:19 +08:00
|
|
|
// -fno-inline-functions overrides OptimizationLevel > 1.
|
2012-03-16 06:31:42 +08:00
|
|
|
Opts.NoInline = Args.hasArg(OPT_fno_inline);
|
2016-05-25 04:40:51 +08:00
|
|
|
if (Arg* InlineArg = Args.getLastArg(options::OPT_finline_functions,
|
|
|
|
options::OPT_fno_inline_functions)) {
|
|
|
|
Opts.setInlining(
|
|
|
|
InlineArg->getOption().matches(options::OPT_finline_functions) ?
|
|
|
|
CodeGenOptions::NormalInlining : CodeGenOptions::OnlyAlwaysInlining);
|
|
|
|
}
|
2009-12-01 11:16:53 +08:00
|
|
|
|
2015-03-18 04:03:11 +08:00
|
|
|
if (Arg *A = Args.getLastArg(OPT_fveclib)) {
|
|
|
|
StringRef Name = A->getValue();
|
|
|
|
if (Name == "Accelerate")
|
|
|
|
Opts.setVecLib(CodeGenOptions::Accelerate);
|
|
|
|
else if (Name == "none")
|
|
|
|
Opts.setVecLib(CodeGenOptions::NoLibrary);
|
|
|
|
else
|
|
|
|
Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name;
|
|
|
|
}
|
|
|
|
|
2015-10-08 12:24:12 +08:00
|
|
|
if (Arg *A = Args.getLastArg(OPT_debug_info_kind_EQ)) {
|
2016-01-06 09:37:57 +08:00
|
|
|
unsigned Val =
|
|
|
|
llvm::StringSwitch<unsigned>(A->getValue())
|
2016-02-02 19:06:51 +08:00
|
|
|
.Case("line-tables-only", codegenoptions::DebugLineTablesOnly)
|
|
|
|
.Case("limited", codegenoptions::LimitedDebugInfo)
|
|
|
|
.Case("standalone", codegenoptions::FullDebugInfo)
|
2016-01-06 09:37:57 +08:00
|
|
|
.Default(~0U);
|
|
|
|
if (Val == ~0U)
|
|
|
|
Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
|
|
|
|
<< A->getValue();
|
|
|
|
else
|
2016-02-02 19:06:51 +08:00
|
|
|
Opts.setDebugInfo(static_cast<codegenoptions::DebugInfoKind>(Val));
|
2012-04-27 15:24:20 +08:00
|
|
|
}
|
2015-12-19 10:24:10 +08:00
|
|
|
if (Arg *A = Args.getLastArg(OPT_debugger_tuning_EQ)) {
|
2016-01-06 09:37:57 +08:00
|
|
|
unsigned Val = llvm::StringSwitch<unsigned>(A->getValue())
|
2016-02-06 07:23:25 +08:00
|
|
|
.Case("gdb", unsigned(llvm::DebuggerKind::GDB))
|
|
|
|
.Case("lldb", unsigned(llvm::DebuggerKind::LLDB))
|
|
|
|
.Case("sce", unsigned(llvm::DebuggerKind::SCE))
|
2016-01-06 09:37:57 +08:00
|
|
|
.Default(~0U);
|
|
|
|
if (Val == ~0U)
|
|
|
|
Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
|
|
|
|
<< A->getValue();
|
|
|
|
else
|
2016-02-06 07:23:25 +08:00
|
|
|
Opts.setDebuggerTuning(static_cast<llvm::DebuggerKind>(Val));
|
2015-12-19 10:24:10 +08:00
|
|
|
}
|
2015-10-08 12:24:12 +08:00
|
|
|
Opts.DwarfVersion = getLastArgIntValue(Args, OPT_dwarf_version_EQ, 0, Diags);
|
2012-10-19 05:52:18 +08:00
|
|
|
Opts.DebugColumnInfo = Args.hasArg(OPT_dwarf_column_info);
|
2015-10-08 12:24:12 +08:00
|
|
|
Opts.EmitCodeView = Args.hasArg(OPT_gcodeview);
|
2016-02-25 04:46:36 +08:00
|
|
|
Opts.WholeProgramVTables = Args.hasArg(OPT_fwhole_program_vtables);
|
2016-04-29 01:09:37 +08:00
|
|
|
Opts.LTOVisibilityPublicStd = Args.hasArg(OPT_flto_visibility_public_std);
|
2013-02-23 07:50:16 +08:00
|
|
|
Opts.SplitDwarfFile = Args.getLastArgValue(OPT_split_dwarf_file);
|
2015-08-28 03:46:20 +08:00
|
|
|
Opts.DebugTypeExtRefs = Args.hasArg(OPT_dwarf_ext_refs);
|
2016-06-02 08:24:20 +08:00
|
|
|
Opts.DebugExplicitImport = Triple.isPS4CPU();
|
2012-04-27 15:24:20 +08:00
|
|
|
|
2015-10-13 04:21:08 +08:00
|
|
|
for (const auto &Arg : Args.getAllArgValues(OPT_fdebug_prefix_map_EQ))
|
|
|
|
Opts.DebugPrefixMap.insert(StringRef(Arg).split('='));
|
|
|
|
|
2015-04-15 09:16:18 +08:00
|
|
|
if (const Arg *A =
|
|
|
|
Args.getLastArg(OPT_emit_llvm_uselists, OPT_no_emit_llvm_uselists))
|
|
|
|
Opts.EmitLLVMUseLists = A->getOption().getID() == OPT_emit_llvm_uselists;
|
|
|
|
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.DisableLLVMOpts = Args.hasArg(OPT_disable_llvm_optzns);
|
2015-07-18 04:09:56 +08:00
|
|
|
Opts.DisableLLVMPasses = Args.hasArg(OPT_disable_llvm_passes);
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.DisableRedZone = Args.hasArg(OPT_disable_red_zone);
|
2011-03-18 10:56:14 +08:00
|
|
|
Opts.ForbidGuardVariables = Args.hasArg(OPT_fforbid_guard_variables);
|
IRgen: Add a -fuse-register-sized-bitfield-access option, for testing.
- Changes bit-field access policy to try to use (aligned) register sized accesses.
The idea here is that by using larger accesses we expose more coalescing
potential to the backend when we have situations like adjacent bit-fields in the
same structure (which is common), and that the backend should be smart enough to
narrow the accesses down when no coalescing is done or when it is shown not to
be profitable.
--
$ clang -m32 -O3 -S -o - t.c
_f0: ## @f0
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
movb (%eax), %cl
andb $-128, %cl
orb $1, %cl
movb %cl, (%eax)
movb 1(%eax), %cl
andb $-128, %cl
orb $1, %cl
movb %cl, 1(%eax)
movb 2(%eax), %cl
andb $-128, %cl
orb $1, %cl
movb %cl, 2(%eax)
movb 3(%eax), %cl
andb $-128, %cl
orb $1, %cl
movb %cl, 3(%eax)
popl %ebp
ret
$ clang -m32 -O3 -S -o - t.c -Xclang -fuse-register-sized-bitfield-access
_f0: ## @f0
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
movl $-2139062144, %ecx ## imm = 0xFFFFFFFF80808080
andl (%eax), %ecx
orl $16843009, %ecx ## imm = 0x1010101
movl %ecx, (%eax)
popl %ebp
ret
--
llvm-svn: 133532
2011-06-22 02:54:46 +08:00
|
|
|
Opts.UseRegisterSizedBitfieldAccess = Args.hasArg(
|
|
|
|
OPT_fuse_register_sized_bitfield_access);
|
2013-04-25 02:09:54 +08:00
|
|
|
Opts.RelaxedAliasing = Args.hasArg(OPT_relaxed_aliasing);
|
2013-10-12 04:48:38 +08:00
|
|
|
Opts.StructPathTBAA = !Args.hasArg(OPT_no_struct_path_tbaa);
|
2010-05-21 00:54:55 +08:00
|
|
|
Opts.DwarfDebugFlags = Args.getLastArgValue(OPT_dwarf_debug_flags);
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.MergeAllConstants = !Args.hasArg(OPT_fno_merge_all_constants);
|
|
|
|
Opts.NoCommon = Args.hasArg(OPT_fno_common);
|
|
|
|
Opts.NoImplicitFloat = Args.hasArg(OPT_no_implicit_float);
|
2013-04-11 05:30:03 +08:00
|
|
|
Opts.OptimizeSize = getOptimizationLevelSize(Args);
|
2010-06-08 07:19:17 +08:00
|
|
|
Opts.SimplifyLibCalls = !(Args.hasArg(OPT_fno_builtin) ||
|
|
|
|
Args.hasArg(OPT_ffreestanding));
|
2016-01-06 22:35:46 +08:00
|
|
|
if (Opts.SimplifyLibCalls)
|
|
|
|
getAllNoBuiltinFuncValues(Args, Opts.NoBuiltinFuncs);
|
2013-08-08 16:34:35 +08:00
|
|
|
Opts.UnrollLoops =
|
|
|
|
Args.hasFlag(OPT_funroll_loops, OPT_fno_unroll_loops,
|
2016-05-04 23:26:28 +08:00
|
|
|
(Opts.OptimizationLevel > 1));
|
2013-11-18 00:03:29 +08:00
|
|
|
Opts.RerollLoops = Args.hasArg(OPT_freroll_loops);
|
2009-12-01 11:16:53 +08:00
|
|
|
|
2014-02-23 08:40:30 +08:00
|
|
|
Opts.DisableIntegratedAS = Args.hasArg(OPT_fno_integrated_as);
|
2013-04-17 02:21:19 +08:00
|
|
|
Opts.Autolink = !Args.hasArg(OPT_fno_autolink);
|
2013-11-13 20:22:39 +08:00
|
|
|
Opts.SampleProfileFile = Args.getLastArgValue(OPT_fprofile_sample_use_EQ);
|
2016-02-05 02:39:09 +08:00
|
|
|
|
2016-03-03 04:59:36 +08:00
|
|
|
setPGOInstrumentor(Opts, Args, Diags);
|
|
|
|
Opts.InstrProfileOutput =
|
|
|
|
Args.getLastArgValue(OPT_fprofile_instrument_path_EQ);
|
|
|
|
Opts.ProfileInstrumentUsePath =
|
|
|
|
Args.getLastArgValue(OPT_fprofile_instrument_use_path_EQ);
|
|
|
|
if (!Opts.ProfileInstrumentUsePath.empty())
|
|
|
|
setPGOUseInstrumentor(Opts, Opts.ProfileInstrumentUsePath);
|
2016-02-05 02:39:09 +08:00
|
|
|
|
2015-08-06 07:27:40 +08:00
|
|
|
Opts.CoverageMapping =
|
|
|
|
Args.hasFlag(OPT_fcoverage_mapping, OPT_fno_coverage_mapping, false);
|
2014-08-09 07:41:24 +08:00
|
|
|
Opts.DumpCoverageMapping = Args.hasArg(OPT_dump_coverage_mapping);
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.AsmVerbose = Args.hasArg(OPT_masm_verbose);
|
2016-04-08 05:46:12 +08:00
|
|
|
Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new);
|
2011-06-16 07:02:42 +08:00
|
|
|
Opts.ObjCAutoRefCountExceptions = Args.hasArg(OPT_fobjc_arc_exceptions);
|
2010-03-20 12:15:41 +08:00
|
|
|
Opts.CXAAtExit = !Args.hasArg(OPT_fno_use_cxa_atexit);
|
|
|
|
Opts.CXXCtorDtorAliases = Args.hasArg(OPT_mconstructor_aliases);
|
2014-05-08 10:28:32 +08:00
|
|
|
Opts.CodeModel = getCodeModel(Args, Diags);
|
2010-05-21 00:54:55 +08:00
|
|
|
Opts.DebugPass = Args.getLastArgValue(OPT_mdebug_pass);
|
2015-11-24 01:30:31 +08:00
|
|
|
Opts.DisableFPElim =
|
|
|
|
(Args.hasArg(OPT_mdisable_fp_elim) || Args.hasArg(OPT_pg));
|
2013-06-22 05:15:32 +08:00
|
|
|
Opts.DisableFree = Args.hasArg(OPT_disable_free);
|
2016-03-14 21:23:58 +08:00
|
|
|
Opts.DiscardValueNames = Args.hasArg(OPT_discard_value_names);
|
2012-01-23 16:29:12 +08:00
|
|
|
Opts.DisableTailCalls = Args.hasArg(OPT_mdisable_tail_calls);
|
2010-05-21 00:54:55 +08:00
|
|
|
Opts.FloatABI = Args.getLastArgValue(OPT_mfloat_abi);
|
2010-12-04 09:51:33 +08:00
|
|
|
Opts.LessPreciseFPMAD = Args.hasArg(OPT_cl_mad_enable);
|
2010-05-21 00:54:55 +08:00
|
|
|
Opts.LimitFloatPrecision = Args.getLastArgValue(OPT_mlimit_float_precision);
|
2011-12-10 07:41:18 +08:00
|
|
|
Opts.NoInfsFPMath = (Args.hasArg(OPT_menable_no_infinities) ||
|
2014-12-11 00:41:14 +08:00
|
|
|
Args.hasArg(OPT_cl_finite_math_only) ||
|
2011-12-10 07:41:18 +08:00
|
|
|
Args.hasArg(OPT_cl_fast_relaxed_math));
|
|
|
|
Opts.NoNaNsFPMath = (Args.hasArg(OPT_menable_no_nans) ||
|
2014-12-11 00:41:14 +08:00
|
|
|
Args.hasArg(OPT_cl_unsafe_math_optimizations) ||
|
|
|
|
Args.hasArg(OPT_cl_finite_math_only) ||
|
2011-12-10 07:41:18 +08:00
|
|
|
Args.hasArg(OPT_cl_fast_relaxed_math));
|
2015-01-24 00:40:50 +08:00
|
|
|
Opts.NoSignedZeros = Args.hasArg(OPT_fno_signed_zeros);
|
2015-04-09 23:03:23 +08:00
|
|
|
Opts.ReciprocalMath = Args.hasArg(OPT_freciprocal_math);
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.NoZeroInitializedInBSS = Args.hasArg(OPT_mno_zero_initialized_in_bss);
|
2011-03-23 00:48:17 +08:00
|
|
|
Opts.BackendOptions = Args.getAllArgValues(OPT_backend_option);
|
2013-06-15 01:17:23 +08:00
|
|
|
Opts.NumRegisterParameters = getLastArgIntValue(Args, OPT_mregparm, 0, Diags);
|
2011-06-21 08:14:18 +08:00
|
|
|
Opts.NoExecStack = Args.hasArg(OPT_mno_exec_stack);
|
2014-08-27 02:40:25 +08:00
|
|
|
Opts.FatalWarnings = Args.hasArg(OPT_massembler_fatal_warnings);
|
2013-04-04 14:29:47 +08:00
|
|
|
Opts.EnableSegmentedStacks = Args.hasArg(OPT_split_stacks);
|
2010-05-27 13:39:39 +08:00
|
|
|
Opts.RelaxAll = Args.hasArg(OPT_mrelax_all);
|
2015-12-22 06:09:34 +08:00
|
|
|
Opts.IncrementalLinkerCompatible =
|
|
|
|
Args.hasArg(OPT_mincremental_linker_compatible);
|
2010-07-01 09:31:45 +08:00
|
|
|
Opts.OmitLeafFramePointer = Args.hasArg(OPT_momit_leaf_frame_pointer);
|
2011-03-29 06:49:28 +08:00
|
|
|
Opts.SaveTempLabels = Args.hasArg(OPT_msave_temp_labels);
|
2011-10-18 07:05:52 +08:00
|
|
|
Opts.NoDwarfDirectoryAsm = Args.hasArg(OPT_fno_dwarf_directory_asm);
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.SoftFloat = Args.hasArg(OPT_msoft_float);
|
2012-03-28 07:58:37 +08:00
|
|
|
Opts.StrictEnums = Args.hasArg(OPT_fstrict_enums);
|
2015-09-16 05:46:47 +08:00
|
|
|
Opts.StrictVTablePointers = Args.hasArg(OPT_fstrict_vtable_pointers);
|
2012-01-02 22:19:45 +08:00
|
|
|
Opts.UnsafeFPMath = Args.hasArg(OPT_menable_unsafe_fp_math) ||
|
|
|
|
Args.hasArg(OPT_cl_unsafe_math_optimizations) ||
|
2010-12-04 09:51:23 +08:00
|
|
|
Args.hasArg(OPT_cl_fast_relaxed_math);
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.UnwindTables = Args.hasArg(OPT_munwind_tables);
|
2010-05-21 00:54:55 +08:00
|
|
|
Opts.RelocationModel = Args.getLastArgValue(OPT_mrelocation_model, "pic");
|
2014-10-04 05:57:44 +08:00
|
|
|
Opts.ThreadModel = Args.getLastArgValue(OPT_mthread_model, "posix");
|
|
|
|
if (Opts.ThreadModel != "posix" && Opts.ThreadModel != "single")
|
|
|
|
Diags.Report(diag::err_drv_invalid_value)
|
|
|
|
<< Args.getLastArg(OPT_mthread_model)->getAsString(Args)
|
|
|
|
<< Opts.ThreadModel;
|
2012-02-03 14:27:22 +08:00
|
|
|
Opts.TrapFuncName = Args.getLastArgValue(OPT_ftrap_function_EQ);
|
2012-06-19 09:26:10 +08:00
|
|
|
Opts.UseInitArray = Args.hasArg(OPT_fuse_init_array);
|
2009-12-01 11:16:53 +08:00
|
|
|
|
2013-10-11 11:35:10 +08:00
|
|
|
Opts.FunctionSections = Args.hasFlag(OPT_ffunction_sections,
|
|
|
|
OPT_fno_function_sections, false);
|
|
|
|
Opts.DataSections = Args.hasFlag(OPT_fdata_sections,
|
|
|
|
OPT_fno_data_sections, false);
|
2015-02-21 02:08:57 +08:00
|
|
|
Opts.UniqueSectionNames = Args.hasFlag(OPT_funique_section_names,
|
|
|
|
OPT_fno_unique_section_names, true);
|
|
|
|
|
2014-10-24 08:49:29 +08:00
|
|
|
Opts.MergeFunctions = Args.hasArg(OPT_fmerge_functions);
|
2010-04-13 08:38:24 +08:00
|
|
|
|
2016-04-06 01:50:43 +08:00
|
|
|
Opts.NoUseJumpTables = Args.hasArg(OPT_fno_jump_tables);
|
|
|
|
|
2015-10-16 04:35:53 +08:00
|
|
|
Opts.PrepareForLTO = Args.hasArg(OPT_flto, OPT_flto_EQ);
|
|
|
|
const Arg *A = Args.getLastArg(OPT_flto, OPT_flto_EQ);
|
2016-03-15 08:04:44 +08:00
|
|
|
Opts.EmitSummaryIndex = A && A->containsValue("thin");
|
2015-12-08 03:21:34 +08:00
|
|
|
if (Arg *A = Args.getLastArg(OPT_fthinlto_index_EQ)) {
|
|
|
|
if (IK != IK_LLVM_IR)
|
|
|
|
Diags.Report(diag::err_drv_argument_only_allowed_with)
|
|
|
|
<< A->getAsString(Args) << "-x ir";
|
|
|
|
Opts.ThinLTOIndexFile = Args.getLastArgValue(OPT_fthinlto_index_EQ);
|
|
|
|
}
|
2015-07-07 00:23:00 +08:00
|
|
|
|
2015-02-14 09:35:12 +08:00
|
|
|
Opts.MSVolatile = Args.hasArg(OPT_fms_volatile);
|
|
|
|
|
2013-06-25 09:49:44 +08:00
|
|
|
Opts.VectorizeBB = Args.hasArg(OPT_vectorize_slp_aggressive);
|
|
|
|
Opts.VectorizeLoop = Args.hasArg(OPT_vectorize_loops);
|
|
|
|
Opts.VectorizeSLP = Args.hasArg(OPT_vectorize_slp);
|
|
|
|
|
2010-05-21 00:54:55 +08:00
|
|
|
Opts.MainFileName = Args.getLastArgValue(OPT_main_file_name);
|
2010-02-13 07:47:27 +08:00
|
|
|
Opts.VerifyModule = !Args.hasArg(OPT_disable_llvm_verifier);
|
2010-04-25 01:56:46 +08:00
|
|
|
|
2013-03-20 09:38:16 +08:00
|
|
|
Opts.DisableGCov = Args.hasArg(OPT_test_coverage);
|
2011-04-22 07:44:07 +08:00
|
|
|
Opts.EmitGcovArcs = Args.hasArg(OPT_femit_coverage_data);
|
|
|
|
Opts.EmitGcovNotes = Args.hasArg(OPT_femit_coverage_notes);
|
2013-03-07 16:28:53 +08:00
|
|
|
if (Opts.EmitGcovArcs || Opts.EmitGcovNotes) {
|
2014-09-02 02:50:05 +08:00
|
|
|
Opts.CoverageFile = Args.getLastArgValue(OPT_coverage_file);
|
2013-03-07 16:28:53 +08:00
|
|
|
Opts.CoverageExtraChecksum = Args.hasArg(OPT_coverage_cfg_checksum);
|
2013-03-20 10:14:38 +08:00
|
|
|
Opts.CoverageNoFunctionNamesInData =
|
|
|
|
Args.hasArg(OPT_coverage_no_function_names_in_data);
|
2015-03-17 07:52:21 +08:00
|
|
|
Opts.CoverageExitBlockBeforeBody =
|
|
|
|
Args.hasArg(OPT_coverage_exit_block_before_body);
|
2013-03-07 16:28:53 +08:00
|
|
|
if (Args.hasArg(OPT_coverage_version_EQ)) {
|
|
|
|
StringRef CoverageVersion = Args.getLastArgValue(OPT_coverage_version_EQ);
|
|
|
|
if (CoverageVersion.size() != 4) {
|
|
|
|
Diags.Report(diag::err_drv_invalid_value)
|
|
|
|
<< Args.getLastArg(OPT_coverage_version_EQ)->getAsString(Args)
|
|
|
|
<< CoverageVersion;
|
|
|
|
} else {
|
2013-03-14 13:14:01 +08:00
|
|
|
memcpy(Opts.CoverageVersion, CoverageVersion.data(), 4);
|
2013-03-07 16:28:53 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-05-12 00:26:03 +08:00
|
|
|
// Handle -fembed-bitcode option.
|
|
|
|
if (Arg *A = Args.getLastArg(OPT_fembed_bitcode_EQ)) {
|
|
|
|
StringRef Name = A->getValue();
|
|
|
|
unsigned Model = llvm::StringSwitch<unsigned>(Name)
|
|
|
|
.Case("off", CodeGenOptions::Embed_Off)
|
|
|
|
.Case("all", CodeGenOptions::Embed_All)
|
|
|
|
.Case("bitcode", CodeGenOptions::Embed_Bitcode)
|
|
|
|
.Case("marker", CodeGenOptions::Embed_Marker)
|
|
|
|
.Default(~0U);
|
|
|
|
if (Model == ~0U) {
|
|
|
|
Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name;
|
|
|
|
Success = false;
|
|
|
|
} else
|
|
|
|
Opts.setEmbedBitcode(
|
|
|
|
static_cast<CodeGenOptions::EmbedBitcodeKind>(Model));
|
|
|
|
}
|
|
|
|
// FIXME: For backend options that are not yet recorded as function
|
|
|
|
// attributes in the IR, keep track of them so we can embed them in a
|
|
|
|
// separate data section and use them when building the bitcode.
|
|
|
|
if (Opts.getEmbedBitcode() == CodeGenOptions::Embed_All) {
|
|
|
|
for (const auto &A : Args) {
|
|
|
|
// Do not encode output and input.
|
|
|
|
if (A->getOption().getID() == options::OPT_o ||
|
|
|
|
A->getOption().getID() == options::OPT_INPUT ||
|
|
|
|
A->getOption().getID() == options::OPT_x ||
|
|
|
|
A->getOption().getID() == options::OPT_fembed_bitcode ||
|
|
|
|
(A->getOption().getGroup().isValid() &&
|
|
|
|
A->getOption().getGroup().getID() == options::OPT_W_Group))
|
|
|
|
continue;
|
|
|
|
ArgStringList ASL;
|
|
|
|
A->render(Args, ASL);
|
|
|
|
for (const auto &arg : ASL) {
|
|
|
|
StringRef ArgStr(arg);
|
|
|
|
Opts.CmdArgs.insert(Opts.CmdArgs.end(), ArgStr.begin(), ArgStr.end());
|
|
|
|
// using \00 to seperate each commandline options.
|
|
|
|
Opts.CmdArgs.push_back('\0');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-03-07 16:28:53 +08:00
|
|
|
|
|
|
|
Opts.InstrumentFunctions = Args.hasArg(OPT_finstrument_functions);
|
|
|
|
Opts.InstrumentForProfiling = Args.hasArg(OPT_pg);
|
|
|
|
Opts.EmitOpenCLArgMetadata = Args.hasArg(OPT_cl_kernel_arg_info);
|
2014-03-28 04:47:30 +08:00
|
|
|
Opts.CompressDebugSections = Args.hasArg(OPT_compress_debug_sections);
|
2016-05-29 10:01:14 +08:00
|
|
|
Opts.RelaxELFRelocations = Args.hasArg(OPT_mrelax_relocations);
|
2011-10-21 10:32:14 +08:00
|
|
|
Opts.DebugCompilationDir = Args.getLastArgValue(OPT_fdebug_compilation_dir);
|
2015-10-28 01:56:59 +08:00
|
|
|
for (auto A : Args.filtered(OPT_mlink_bitcode_file, OPT_mlink_cuda_bitcode)) {
|
|
|
|
unsigned LinkFlags = llvm::Linker::Flags::None;
|
|
|
|
if (A->getOption().matches(OPT_mlink_cuda_bitcode))
|
|
|
|
LinkFlags = llvm::Linker::Flags::LinkOnlyNeeded |
|
|
|
|
llvm::Linker::Flags::InternalizeLinkedSymbols;
|
|
|
|
Opts.LinkBitcodeFiles.push_back(std::make_pair(LinkFlags, A->getValue()));
|
|
|
|
}
|
2015-05-08 02:31:29 +08:00
|
|
|
Opts.SanitizeCoverageType =
|
|
|
|
getLastArgIntValue(Args, OPT_fsanitize_coverage_type, 0, Diags);
|
|
|
|
Opts.SanitizeCoverageIndirectCalls =
|
|
|
|
Args.hasArg(OPT_fsanitize_coverage_indirect_calls);
|
|
|
|
Opts.SanitizeCoverageTraceBB = Args.hasArg(OPT_fsanitize_coverage_trace_bb);
|
|
|
|
Opts.SanitizeCoverageTraceCmp = Args.hasArg(OPT_fsanitize_coverage_trace_cmp);
|
|
|
|
Opts.SanitizeCoverage8bitCounters =
|
|
|
|
Args.hasArg(OPT_fsanitize_coverage_8bit_counters);
|
2016-02-18 05:34:43 +08:00
|
|
|
Opts.SanitizeCoverageTracePC = Args.hasArg(OPT_fsanitize_coverage_trace_pc);
|
2013-01-20 21:12:12 +08:00
|
|
|
Opts.SanitizeMemoryTrackOrigins =
|
2014-03-20 22:58:36 +08:00
|
|
|
getLastArgIntValue(Args, OPT_fsanitize_memory_track_origins_EQ, 0, Diags);
|
2015-07-11 04:07:16 +08:00
|
|
|
Opts.SanitizeMemoryUseAfterDtor =
|
|
|
|
Args.hasArg(OPT_fsanitize_memory_use_after_dtor);
|
2015-12-16 07:00:20 +08:00
|
|
|
Opts.SanitizeCfiCrossDso = Args.hasArg(OPT_fsanitize_cfi_cross_dso);
|
2016-01-16 08:31:22 +08:00
|
|
|
Opts.SanitizeStats = Args.hasArg(OPT_fsanitize_stats);
|
2016-06-02 08:24:20 +08:00
|
|
|
Opts.SanitizeAddressUseAfterScope =
|
|
|
|
Args.hasArg(OPT_fsanitize_address_use_after_scope);
|
2012-08-22 00:16:06 +08:00
|
|
|
Opts.SSPBufferSize =
|
2013-06-15 01:17:23 +08:00
|
|
|
getLastArgIntValue(Args, OPT_stack_protector_buffer_size, 8, Diags);
|
2011-12-06 11:33:03 +08:00
|
|
|
Opts.StackRealignment = Args.hasArg(OPT_mstackrealign);
|
2011-12-06 07:05:23 +08:00
|
|
|
if (Arg *A = Args.getLastArg(OPT_mstack_alignment)) {
|
2012-11-01 12:30:05 +08:00
|
|
|
StringRef Val = A->getValue();
|
2012-10-24 04:05:01 +08:00
|
|
|
unsigned StackAlignment = Opts.StackAlignment;
|
|
|
|
Val.getAsInteger(10, StackAlignment);
|
|
|
|
Opts.StackAlignment = StackAlignment;
|
2011-12-06 07:05:23 +08:00
|
|
|
}
|
2010-06-22 08:03:40 +08:00
|
|
|
|
2015-01-21 03:45:50 +08:00
|
|
|
if (Arg *A = Args.getLastArg(OPT_mstack_probe_size)) {
|
|
|
|
StringRef Val = A->getValue();
|
|
|
|
unsigned StackProbeSize = Opts.StackProbeSize;
|
|
|
|
Val.getAsInteger(0, StackProbeSize);
|
|
|
|
Opts.StackProbeSize = StackProbeSize;
|
|
|
|
}
|
|
|
|
|
2010-04-25 01:56:46 +08:00
|
|
|
if (Arg *A = Args.getLastArg(OPT_fobjc_dispatch_method_EQ)) {
|
2012-11-01 12:30:05 +08:00
|
|
|
StringRef Name = A->getValue();
|
2010-04-25 01:56:46 +08:00
|
|
|
unsigned Method = llvm::StringSwitch<unsigned>(Name)
|
|
|
|
.Case("legacy", CodeGenOptions::Legacy)
|
|
|
|
.Case("non-legacy", CodeGenOptions::NonLegacy)
|
|
|
|
.Case("mixed", CodeGenOptions::Mixed)
|
|
|
|
.Default(~0U);
|
2011-12-23 11:05:38 +08:00
|
|
|
if (Method == ~0U) {
|
2010-04-25 01:56:46 +08:00
|
|
|
Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name;
|
2011-12-23 11:05:38 +08:00
|
|
|
Success = false;
|
|
|
|
} else {
|
2012-10-24 04:05:01 +08:00
|
|
|
Opts.setObjCDispatchMethod(
|
|
|
|
static_cast<CodeGenOptions::ObjCDispatchMethodKind>(Method));
|
2011-12-23 11:05:38 +08:00
|
|
|
}
|
2010-04-25 01:56:46 +08:00
|
|
|
}
|
2011-12-23 11:05:38 +08:00
|
|
|
|
2015-07-29 00:27:56 +08:00
|
|
|
Opts.EmulatedTLS =
|
|
|
|
Args.hasFlag(OPT_femulated_tls, OPT_fno_emulated_tls, false);
|
|
|
|
|
2012-06-28 16:01:44 +08:00
|
|
|
if (Arg *A = Args.getLastArg(OPT_ftlsmodel_EQ)) {
|
2012-11-01 12:30:05 +08:00
|
|
|
StringRef Name = A->getValue();
|
2012-06-28 16:01:44 +08:00
|
|
|
unsigned Model = llvm::StringSwitch<unsigned>(Name)
|
|
|
|
.Case("global-dynamic", CodeGenOptions::GeneralDynamicTLSModel)
|
|
|
|
.Case("local-dynamic", CodeGenOptions::LocalDynamicTLSModel)
|
|
|
|
.Case("initial-exec", CodeGenOptions::InitialExecTLSModel)
|
|
|
|
.Case("local-exec", CodeGenOptions::LocalExecTLSModel)
|
|
|
|
.Default(~0U);
|
|
|
|
if (Model == ~0U) {
|
|
|
|
Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name;
|
|
|
|
Success = false;
|
|
|
|
} else {
|
2012-10-24 04:05:01 +08:00
|
|
|
Opts.setDefaultTLSModel(static_cast<CodeGenOptions::TLSModel>(Model));
|
2012-06-28 16:01:44 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-15 15:51:26 +08:00
|
|
|
if (Arg *A = Args.getLastArg(OPT_ffp_contract)) {
|
|
|
|
StringRef Val = A->getValue();
|
|
|
|
if (Val == "fast")
|
|
|
|
Opts.setFPContractMode(CodeGenOptions::FPC_Fast);
|
|
|
|
else if (Val == "on")
|
|
|
|
Opts.setFPContractMode(CodeGenOptions::FPC_On);
|
|
|
|
else if (Val == "off")
|
|
|
|
Opts.setFPContractMode(CodeGenOptions::FPC_Off);
|
|
|
|
else
|
|
|
|
Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val;
|
|
|
|
}
|
|
|
|
|
2013-06-18 10:46:29 +08:00
|
|
|
if (Arg *A = Args.getLastArg(OPT_fpcc_struct_return, OPT_freg_struct_return)) {
|
|
|
|
if (A->getOption().matches(OPT_fpcc_struct_return)) {
|
|
|
|
Opts.setStructReturnConvention(CodeGenOptions::SRCK_OnStack);
|
|
|
|
} else {
|
|
|
|
assert(A->getOption().matches(OPT_freg_struct_return));
|
|
|
|
Opts.setStructReturnConvention(CodeGenOptions::SRCK_InRegs);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-08 08:17:41 +08:00
|
|
|
Opts.DependentLibraries = Args.getAllArgValues(OPT_dependent_lib);
|
2016-01-16 08:31:22 +08:00
|
|
|
Opts.LinkerOptions = Args.getAllArgValues(OPT_linker_option);
|
2014-06-25 01:02:17 +08:00
|
|
|
bool NeedLocTracking = false;
|
2013-08-08 08:17:41 +08:00
|
|
|
|
2014-06-25 01:02:17 +08:00
|
|
|
if (Arg *A = Args.getLastArg(OPT_Rpass_EQ)) {
|
2014-05-30 03:55:06 +08:00
|
|
|
Opts.OptimizationRemarkPattern =
|
|
|
|
GenerateOptimizationRemarkRegex(Diags, Args, A);
|
2014-06-25 01:02:17 +08:00
|
|
|
NeedLocTracking = true;
|
|
|
|
}
|
2014-05-30 03:55:06 +08:00
|
|
|
|
2014-06-25 01:02:17 +08:00
|
|
|
if (Arg *A = Args.getLastArg(OPT_Rpass_missed_EQ)) {
|
2014-05-30 03:55:06 +08:00
|
|
|
Opts.OptimizationRemarkMissedPattern =
|
|
|
|
GenerateOptimizationRemarkRegex(Diags, Args, A);
|
2014-06-25 01:02:17 +08:00
|
|
|
NeedLocTracking = true;
|
|
|
|
}
|
2014-05-30 03:55:06 +08:00
|
|
|
|
2014-06-25 01:02:17 +08:00
|
|
|
if (Arg *A = Args.getLastArg(OPT_Rpass_analysis_EQ)) {
|
2014-05-30 03:55:06 +08:00
|
|
|
Opts.OptimizationRemarkAnalysisPattern =
|
|
|
|
GenerateOptimizationRemarkRegex(Diags, Args, A);
|
2014-06-25 01:02:17 +08:00
|
|
|
NeedLocTracking = true;
|
|
|
|
}
|
|
|
|
|
2014-10-22 21:00:05 +08:00
|
|
|
// If the user requested to use a sample profile for PGO, then the
|
|
|
|
// backend will need to track source location information so the profile
|
|
|
|
// can be incorporated into the IR.
|
|
|
|
if (!Opts.SampleProfileFile.empty())
|
|
|
|
NeedLocTracking = true;
|
|
|
|
|
|
|
|
// If the user requested a flag that requires source locations available in
|
|
|
|
// the backend, make sure that the backend tracks source location information.
|
2016-02-02 19:06:51 +08:00
|
|
|
if (NeedLocTracking && Opts.getDebugInfo() == codegenoptions::NoDebugInfo)
|
|
|
|
Opts.setDebugInfo(codegenoptions::LocTrackingOnly);
|
2014-05-30 03:55:06 +08:00
|
|
|
|
2015-01-09 13:10:20 +08:00
|
|
|
Opts.RewriteMapFiles = Args.getAllArgValues(OPT_frewrite_map_file);
|
|
|
|
|
Reimplement -fsanitize-recover family of flags.
Introduce the following -fsanitize-recover flags:
- -fsanitize-recover=<list>: Enable recovery for selected checks or
group of checks. It is forbidden to explicitly list unrecoverable
sanitizers here (that is, "address", "unreachable", "return").
- -fno-sanitize-recover=<list>: Disable recovery for selected checks or
group of checks.
- -f(no-)?sanitize-recover is now a synonym for
-f(no-)?sanitize-recover=undefined,integer and will soon be deprecated.
These flags are parsed left to right, and mask of "recoverable"
sanitizer is updated accordingly, much like what we do for -fsanitize= flags.
-fsanitize= and -fsanitize-recover= flag families are independent.
CodeGen change: If there is a single UBSan handler function, responsible
for implementing multiple checks, which have different recoverable setting,
then we emit two handler calls instead of one:
the first one for the set of "unrecoverable" checks, another one - for
set of "recoverable" checks. If all checks implemented by a handler have the
same recoverability setting, then the generated code will be the same.
llvm-svn: 225719
2015-01-13 06:39:12 +08:00
|
|
|
// Parse -fsanitize-recover= arguments.
|
|
|
|
// FIXME: Report unrecoverable sanitizers incorrectly specified here.
|
|
|
|
parseSanitizerKinds("-fsanitize-recover=",
|
|
|
|
Args.getAllArgValues(OPT_fsanitize_recover_EQ), Diags,
|
|
|
|
Opts.SanitizeRecover);
|
2015-06-19 07:59:22 +08:00
|
|
|
parseSanitizerKinds("-fsanitize-trap=",
|
|
|
|
Args.getAllArgValues(OPT_fsanitize_trap_EQ), Diags,
|
|
|
|
Opts.SanitizeTrap);
|
Reimplement -fsanitize-recover family of flags.
Introduce the following -fsanitize-recover flags:
- -fsanitize-recover=<list>: Enable recovery for selected checks or
group of checks. It is forbidden to explicitly list unrecoverable
sanitizers here (that is, "address", "unreachable", "return").
- -fno-sanitize-recover=<list>: Disable recovery for selected checks or
group of checks.
- -f(no-)?sanitize-recover is now a synonym for
-f(no-)?sanitize-recover=undefined,integer and will soon be deprecated.
These flags are parsed left to right, and mask of "recoverable"
sanitizer is updated accordingly, much like what we do for -fsanitize= flags.
-fsanitize= and -fsanitize-recover= flag families are independent.
CodeGen change: If there is a single UBSan handler function, responsible
for implementing multiple checks, which have different recoverable setting,
then we emit two handler calls instead of one:
the first one for the set of "unrecoverable" checks, another one - for
set of "recoverable" checks. If all checks implemented by a handler have the
same recoverability setting, then the generated code will be the same.
llvm-svn: 225719
2015-01-13 06:39:12 +08:00
|
|
|
|
2015-05-08 03:34:16 +08:00
|
|
|
Opts.CudaGpuBinaryFileNames =
|
|
|
|
Args.getAllArgValues(OPT_fcuda_include_gpubinary);
|
|
|
|
|
2016-05-05 07:37:40 +08:00
|
|
|
Opts.Backchain = Args.hasArg(OPT_mbackchain);
|
|
|
|
|
2016-05-13 00:51:36 +08:00
|
|
|
Opts.EmitCheckPathComponentsToStrip = getLastArgIntValue(
|
|
|
|
Args, OPT_fsanitize_undefined_strip_path_components_EQ, 0, Diags);
|
|
|
|
|
2011-12-23 11:05:38 +08:00
|
|
|
return Success;
|
2009-12-01 11:16:53 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts,
|
|
|
|
ArgList &Args) {
|
2012-05-01 22:57:16 +08:00
|
|
|
using namespace options;
|
2010-05-21 00:54:55 +08:00
|
|
|
Opts.OutputFile = Args.getLastArgValue(OPT_dependency_file);
|
|
|
|
Opts.Targets = Args.getAllArgValues(OPT_MT);
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.IncludeSystemHeaders = Args.hasArg(OPT_sys_header_deps);
|
2014-03-14 11:07:38 +08:00
|
|
|
Opts.IncludeModuleFiles = Args.hasArg(OPT_module_file_deps);
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.UsePhonyTargets = Args.hasArg(OPT_MP);
|
2011-02-02 23:41:17 +08:00
|
|
|
Opts.ShowHeaderIncludes = Args.hasArg(OPT_H);
|
2011-02-03 05:11:31 +08:00
|
|
|
Opts.HeaderIncludeOutputFile = Args.getLastArgValue(OPT_header_include_file);
|
2011-07-13 03:35:15 +08:00
|
|
|
Opts.AddMissingHeaderDeps = Args.hasArg(OPT_MG);
|
2013-08-09 08:32:23 +08:00
|
|
|
Opts.PrintShowIncludes = Args.hasArg(OPT_show_includes);
|
2012-02-03 07:45:13 +08:00
|
|
|
Opts.DOTOutputFile = Args.getLastArgValue(OPT_dependency_dot);
|
2014-06-20 03:36:03 +08:00
|
|
|
Opts.ModuleDependencyOutputDir =
|
|
|
|
Args.getLastArgValue(OPT_module_dependency_dir);
|
2015-04-28 02:14:32 +08:00
|
|
|
if (Args.hasArg(OPT_MV))
|
|
|
|
Opts.OutputFormat = DependencyOutputFormat::NMake;
|
2015-08-13 12:04:37 +08:00
|
|
|
// Add sanitizer blacklists as extra dependencies.
|
|
|
|
// They won't be discovered by the regular preprocessor, so
|
|
|
|
// we let make / ninja to know about this implicit dependency.
|
2015-09-03 04:02:38 +08:00
|
|
|
Opts.ExtraDeps = Args.getAllArgValues(OPT_fdepfile_entry);
|
2015-08-14 02:30:25 +08:00
|
|
|
auto ModuleFiles = Args.getAllArgValues(OPT_fmodule_file);
|
|
|
|
Opts.ExtraDeps.insert(Opts.ExtraDeps.end(), ModuleFiles.begin(),
|
|
|
|
ModuleFiles.end());
|
2009-12-01 11:16:53 +08:00
|
|
|
}
|
|
|
|
|
2016-05-28 04:43:00 +08:00
|
|
|
static bool parseShowColorsArgs(const ArgList &Args, bool DefaultColor) {
|
|
|
|
// Color diagnostics default to auto ("on" if terminal supports) in the driver
|
|
|
|
// but default to off in cc1, needing an explicit OPT_fdiagnostics_color.
|
|
|
|
// Support both clang's -f[no-]color-diagnostics and gcc's
|
|
|
|
// -f[no-]diagnostics-colors[=never|always|auto].
|
|
|
|
enum {
|
|
|
|
Colors_On,
|
|
|
|
Colors_Off,
|
|
|
|
Colors_Auto
|
|
|
|
} ShowColors = DefaultColor ? Colors_Auto : Colors_Off;
|
|
|
|
for (Arg *A : Args) {
|
|
|
|
const Option &O = A->getOption();
|
|
|
|
if (!O.matches(options::OPT_fcolor_diagnostics) &&
|
|
|
|
!O.matches(options::OPT_fdiagnostics_color) &&
|
|
|
|
!O.matches(options::OPT_fno_color_diagnostics) &&
|
|
|
|
!O.matches(options::OPT_fno_diagnostics_color) &&
|
|
|
|
!O.matches(options::OPT_fdiagnostics_color_EQ))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (O.matches(options::OPT_fcolor_diagnostics) ||
|
|
|
|
O.matches(options::OPT_fdiagnostics_color)) {
|
|
|
|
ShowColors = Colors_On;
|
|
|
|
} else if (O.matches(options::OPT_fno_color_diagnostics) ||
|
|
|
|
O.matches(options::OPT_fno_diagnostics_color)) {
|
|
|
|
ShowColors = Colors_Off;
|
|
|
|
} else {
|
|
|
|
assert(O.matches(options::OPT_fdiagnostics_color_EQ));
|
|
|
|
StringRef Value(A->getValue());
|
|
|
|
if (Value == "always")
|
|
|
|
ShowColors = Colors_On;
|
|
|
|
else if (Value == "never")
|
|
|
|
ShowColors = Colors_Off;
|
|
|
|
else if (Value == "auto")
|
|
|
|
ShowColors = Colors_Auto;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (ShowColors == Colors_On ||
|
|
|
|
(ShowColors == Colors_Auto && llvm::sys::Process::StandardErrHasColors()))
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-03-14 04:09:56 +08:00
|
|
|
bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
|
2016-05-28 04:43:00 +08:00
|
|
|
DiagnosticsEngine *Diags,
|
|
|
|
bool DefaultDiagColor) {
|
2012-05-01 22:57:16 +08:00
|
|
|
using namespace options;
|
2011-12-23 11:05:38 +08:00
|
|
|
bool Success = true;
|
|
|
|
|
2011-04-08 02:11:14 +08:00
|
|
|
Opts.DiagnosticLogFile = Args.getLastArgValue(OPT_diagnostic_log_file);
|
2014-10-24 06:20:11 +08:00
|
|
|
if (Arg *A =
|
|
|
|
Args.getLastArg(OPT_diagnostic_serialized_file, OPT__serialize_diags))
|
|
|
|
Opts.DiagnosticSerializationFile = A->getValue();
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.IgnoreWarnings = Args.hasArg(OPT_w);
|
|
|
|
Opts.NoRewriteMacros = Args.hasArg(OPT_Wno_rewrite_macros);
|
|
|
|
Opts.Pedantic = Args.hasArg(OPT_pedantic);
|
|
|
|
Opts.PedanticErrors = Args.hasArg(OPT_pedantic_errors);
|
|
|
|
Opts.ShowCarets = !Args.hasArg(OPT_fno_caret_diagnostics);
|
2016-05-28 04:43:00 +08:00
|
|
|
Opts.ShowColors = parseShowColorsArgs(Args, DefaultDiagColor);
|
2011-05-22 01:07:29 +08:00
|
|
|
Opts.ShowColumn = Args.hasFlag(OPT_fshow_column,
|
|
|
|
OPT_fno_show_column,
|
|
|
|
/*Default=*/true);
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.ShowFixits = !Args.hasArg(OPT_fno_diagnostics_fixit_info);
|
|
|
|
Opts.ShowLocation = !Args.hasArg(OPT_fno_show_source_location);
|
|
|
|
Opts.ShowOptionNames = Args.hasArg(OPT_fdiagnostics_show_option);
|
2010-06-11 13:57:47 +08:00
|
|
|
|
2013-09-11 08:38:02 +08:00
|
|
|
llvm::sys::Process::UseANSIEscapeCodes(Args.hasArg(OPT_fansi_escape_codes));
|
|
|
|
|
2011-03-28 04:00:08 +08:00
|
|
|
// Default behavior is to not to show note include stacks.
|
|
|
|
Opts.ShowNoteIncludeStack = false;
|
2011-03-27 09:50:55 +08:00
|
|
|
if (Arg *A = Args.getLastArg(OPT_fdiagnostics_show_note_include_stack,
|
|
|
|
OPT_fno_diagnostics_show_note_include_stack))
|
2011-03-28 04:00:08 +08:00
|
|
|
if (A->getOption().matches(OPT_fdiagnostics_show_note_include_stack))
|
|
|
|
Opts.ShowNoteIncludeStack = true;
|
2011-03-27 09:50:55 +08:00
|
|
|
|
2011-07-23 18:55:15 +08:00
|
|
|
StringRef ShowOverloads =
|
2010-06-11 13:57:47 +08:00
|
|
|
Args.getLastArgValue(OPT_fshow_overloads_EQ, "all");
|
|
|
|
if (ShowOverloads == "best")
|
2012-10-24 07:11:23 +08:00
|
|
|
Opts.setShowOverloads(Ovl_Best);
|
2010-06-11 13:57:47 +08:00
|
|
|
else if (ShowOverloads == "all")
|
2012-10-24 07:11:23 +08:00
|
|
|
Opts.setShowOverloads(Ovl_All);
|
2011-12-23 11:05:38 +08:00
|
|
|
else {
|
2012-03-14 04:09:56 +08:00
|
|
|
Success = false;
|
|
|
|
if (Diags)
|
|
|
|
Diags->Report(diag::err_drv_invalid_value)
|
2010-06-11 13:57:47 +08:00
|
|
|
<< Args.getLastArg(OPT_fshow_overloads_EQ)->getAsString(Args)
|
|
|
|
<< ShowOverloads;
|
2011-12-23 11:05:38 +08:00
|
|
|
}
|
2010-06-11 13:57:47 +08:00
|
|
|
|
2011-07-23 18:55:15 +08:00
|
|
|
StringRef ShowCategory =
|
2010-05-21 00:54:55 +08:00
|
|
|
Args.getLastArgValue(OPT_fdiagnostics_show_category, "none");
|
2010-05-05 05:55:25 +08:00
|
|
|
if (ShowCategory == "none")
|
|
|
|
Opts.ShowCategories = 0;
|
|
|
|
else if (ShowCategory == "id")
|
|
|
|
Opts.ShowCategories = 1;
|
|
|
|
else if (ShowCategory == "name")
|
|
|
|
Opts.ShowCategories = 2;
|
2011-12-23 11:05:38 +08:00
|
|
|
else {
|
2012-03-14 04:09:56 +08:00
|
|
|
Success = false;
|
|
|
|
if (Diags)
|
|
|
|
Diags->Report(diag::err_drv_invalid_value)
|
2010-05-05 05:55:25 +08:00
|
|
|
<< Args.getLastArg(OPT_fdiagnostics_show_category)->getAsString(Args)
|
|
|
|
<< ShowCategory;
|
2011-12-23 11:05:38 +08:00
|
|
|
}
|
2010-10-21 11:16:25 +08:00
|
|
|
|
2011-07-23 18:55:15 +08:00
|
|
|
StringRef Format =
|
2011-05-22 01:07:29 +08:00
|
|
|
Args.getLastArgValue(OPT_fdiagnostics_format, "clang");
|
|
|
|
if (Format == "clang")
|
2012-10-24 07:11:23 +08:00
|
|
|
Opts.setFormat(DiagnosticOptions::Clang);
|
2011-12-23 11:05:38 +08:00
|
|
|
else if (Format == "msvc")
|
2015-02-03 03:30:52 +08:00
|
|
|
Opts.setFormat(DiagnosticOptions::MSVC);
|
2013-09-24 08:08:55 +08:00
|
|
|
else if (Format == "msvc-fallback") {
|
2015-02-03 03:30:52 +08:00
|
|
|
Opts.setFormat(DiagnosticOptions::MSVC);
|
2013-09-24 08:08:55 +08:00
|
|
|
Opts.CLFallbackMode = true;
|
|
|
|
} else if (Format == "vi")
|
2012-10-24 07:11:23 +08:00
|
|
|
Opts.setFormat(DiagnosticOptions::Vi);
|
2011-12-23 11:05:38 +08:00
|
|
|
else {
|
2012-03-14 04:09:56 +08:00
|
|
|
Success = false;
|
|
|
|
if (Diags)
|
|
|
|
Diags->Report(diag::err_drv_invalid_value)
|
2011-05-22 01:07:29 +08:00
|
|
|
<< Args.getLastArg(OPT_fdiagnostics_format)->getAsString(Args)
|
|
|
|
<< Format;
|
2011-12-23 11:05:38 +08:00
|
|
|
}
|
2015-06-13 15:11:40 +08:00
|
|
|
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.ShowSourceRanges = Args.hasArg(OPT_fdiagnostics_print_source_range_info);
|
2010-08-20 04:24:43 +08:00
|
|
|
Opts.ShowParseableFixits = Args.hasArg(OPT_fdiagnostics_parseable_fixits);
|
2012-11-15 07:55:25 +08:00
|
|
|
Opts.ShowPresumedLoc = !Args.hasArg(OPT_fno_diagnostics_use_presumed_location);
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.VerifyDiagnostics = Args.hasArg(OPT_verify);
|
2015-06-13 15:11:40 +08:00
|
|
|
DiagnosticLevelMask DiagMask = DiagnosticLevelMask::None;
|
|
|
|
Success &= parseDiagnosticLevelMask("-verify-ignore-unexpected=",
|
|
|
|
Args.getAllArgValues(OPT_verify_ignore_unexpected_EQ),
|
|
|
|
Diags, DiagMask);
|
|
|
|
if (Args.hasArg(OPT_verify_ignore_unexpected))
|
|
|
|
DiagMask = DiagnosticLevelMask::All;
|
|
|
|
Opts.setVerifyIgnoreUnexpected(DiagMask);
|
2012-06-27 02:18:47 +08:00
|
|
|
Opts.ElideType = !Args.hasArg(OPT_fno_elide_type);
|
|
|
|
Opts.ShowTemplateTree = Args.hasArg(OPT_fdiagnostics_show_template_tree);
|
2013-06-15 01:17:23 +08:00
|
|
|
Opts.ErrorLimit = getLastArgIntValue(Args, OPT_ferror_limit, 0, Diags);
|
|
|
|
Opts.MacroBacktraceLimit =
|
|
|
|
getLastArgIntValue(Args, OPT_fmacro_backtrace_limit,
|
2010-05-05 01:13:42 +08:00
|
|
|
DiagnosticOptions::DefaultMacroBacktraceLimit, Diags);
|
2013-06-15 01:17:23 +08:00
|
|
|
Opts.TemplateBacktraceLimit = getLastArgIntValue(
|
|
|
|
Args, OPT_ftemplate_backtrace_limit,
|
|
|
|
DiagnosticOptions::DefaultTemplateBacktraceLimit, Diags);
|
|
|
|
Opts.ConstexprBacktraceLimit = getLastArgIntValue(
|
|
|
|
Args, OPT_fconstexpr_backtrace_limit,
|
|
|
|
DiagnosticOptions::DefaultConstexprBacktraceLimit, Diags);
|
2014-12-17 05:39:02 +08:00
|
|
|
Opts.SpellCheckingLimit = getLastArgIntValue(
|
|
|
|
Args, OPT_fspell_checking_limit,
|
|
|
|
DiagnosticOptions::DefaultSpellCheckingLimit, Diags);
|
2013-06-15 01:17:23 +08:00
|
|
|
Opts.TabStop = getLastArgIntValue(Args, OPT_ftabstop,
|
2010-01-13 11:06:50 +08:00
|
|
|
DiagnosticOptions::DefaultTabStop, Diags);
|
|
|
|
if (Opts.TabStop == 0 || Opts.TabStop > DiagnosticOptions::MaxTabStop) {
|
|
|
|
Opts.TabStop = DiagnosticOptions::DefaultTabStop;
|
2012-03-14 04:09:56 +08:00
|
|
|
if (Diags)
|
|
|
|
Diags->Report(diag::warn_ignoring_ftabstop_value)
|
|
|
|
<< Opts.TabStop << DiagnosticOptions::DefaultTabStop;
|
2010-01-13 11:06:50 +08:00
|
|
|
}
|
2013-06-15 01:17:23 +08:00
|
|
|
Opts.MessageLength = getLastArgIntValue(Args, OPT_fmessage_length, 0, Diags);
|
Use -Rblah, not -Wblah, to control remark diagnostics. This was always the
intent when we added remark support, but was never implemented in the general
case, because the first -R flags didn't need it. (-Rpass= had special handling
to accomodate its argument.)
-Rno-foo, -Reverything, and -Rno-everything can be used to turn off a remark,
or to turn on or off all remarks. Per discussion on cfe-commits, -Weverything
does not affect remarks, and -Reverything does not affect warnings or errors.
The only "real" -R flag we have right now is -Rmodule-build; that flag is
effectively renamed from -Wmodule-build to -Rmodule-build by this change.
-Wpass and -Wno-pass (and their friends) are also renamed to -Rpass and
-Rno-pass by this change; it's not completely clear whether we intended to have
a -Rpass (with no =pattern), but that is unchanged by this commit, other than
the flag name. The default pattern is effectively one which matches no passes.
In future, we may want to make the default pattern be .*, so that -Reverything
works for -Rpass properly.
llvm-svn: 215046
2014-08-07 08:24:21 +08:00
|
|
|
addDiagnosticArgs(Args, OPT_W_Group, OPT_W_value_Group, Opts.Warnings);
|
|
|
|
addDiagnosticArgs(Args, OPT_R_Group, OPT_R_value_Group, Opts.Remarks);
|
2011-12-23 11:05:38 +08:00
|
|
|
|
|
|
|
return Success;
|
2009-12-01 11:16:53 +08:00
|
|
|
}
|
|
|
|
|
2010-11-04 06:45:23 +08:00
|
|
|
static void ParseFileSystemArgs(FileSystemOptions &Opts, ArgList &Args) {
|
|
|
|
Opts.WorkingDir = Args.getLastArgValue(OPT_working_directory);
|
|
|
|
}
|
|
|
|
|
2015-11-04 02:33:07 +08:00
|
|
|
/// Parse the argument to the -ftest-module-file-extension
|
|
|
|
/// command-line argument.
|
|
|
|
///
|
|
|
|
/// \returns true on error, false on success.
|
|
|
|
static bool parseTestModuleFileExtensionArg(StringRef Arg,
|
|
|
|
std::string &BlockName,
|
|
|
|
unsigned &MajorVersion,
|
|
|
|
unsigned &MinorVersion,
|
|
|
|
bool &Hashed,
|
|
|
|
std::string &UserInfo) {
|
|
|
|
SmallVector<StringRef, 5> Args;
|
|
|
|
Arg.split(Args, ':', 5);
|
|
|
|
if (Args.size() < 5)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
BlockName = Args[0];
|
|
|
|
if (Args[1].getAsInteger(10, MajorVersion)) return true;
|
|
|
|
if (Args[2].getAsInteger(10, MinorVersion)) return true;
|
|
|
|
if (Args[3].getAsInteger(2, Hashed)) return true;
|
|
|
|
if (Args.size() > 4)
|
|
|
|
UserInfo = Args[4];
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2010-06-08 07:22:09 +08:00
|
|
|
static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
|
2011-09-26 07:23:43 +08:00
|
|
|
DiagnosticsEngine &Diags) {
|
2012-05-01 22:57:16 +08:00
|
|
|
using namespace options;
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.ProgramAction = frontend::ParseSyntaxOnly;
|
|
|
|
if (const Arg *A = Args.getLastArg(OPT_Action_Group)) {
|
|
|
|
switch (A->getOption().getID()) {
|
|
|
|
default:
|
2011-09-23 13:06:16 +08:00
|
|
|
llvm_unreachable("Invalid option in group!");
|
2012-07-31 17:37:40 +08:00
|
|
|
case OPT_ast_list:
|
|
|
|
Opts.ProgramAction = frontend::ASTDeclList; break;
|
2009-12-01 11:16:53 +08:00
|
|
|
case OPT_ast_dump:
|
2014-08-12 06:11:07 +08:00
|
|
|
case OPT_ast_dump_lookups:
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.ProgramAction = frontend::ASTDump; break;
|
|
|
|
case OPT_ast_print:
|
|
|
|
Opts.ProgramAction = frontend::ASTPrint; break;
|
|
|
|
case OPT_ast_view:
|
|
|
|
Opts.ProgramAction = frontend::ASTView; break;
|
|
|
|
case OPT_dump_raw_tokens:
|
|
|
|
Opts.ProgramAction = frontend::DumpRawTokens; break;
|
|
|
|
case OPT_dump_tokens:
|
|
|
|
Opts.ProgramAction = frontend::DumpTokens; break;
|
|
|
|
case OPT_S:
|
|
|
|
Opts.ProgramAction = frontend::EmitAssembly; break;
|
|
|
|
case OPT_emit_llvm_bc:
|
|
|
|
Opts.ProgramAction = frontend::EmitBC; break;
|
|
|
|
case OPT_emit_html:
|
|
|
|
Opts.ProgramAction = frontend::EmitHTML; break;
|
|
|
|
case OPT_emit_llvm:
|
|
|
|
Opts.ProgramAction = frontend::EmitLLVM; break;
|
|
|
|
case OPT_emit_llvm_only:
|
|
|
|
Opts.ProgramAction = frontend::EmitLLVMOnly; break;
|
2010-05-26 02:41:01 +08:00
|
|
|
case OPT_emit_codegen_only:
|
|
|
|
Opts.ProgramAction = frontend::EmitCodeGenOnly; break;
|
2010-02-03 09:18:43 +08:00
|
|
|
case OPT_emit_obj:
|
|
|
|
Opts.ProgramAction = frontend::EmitObj; break;
|
2010-04-24 09:30:46 +08:00
|
|
|
case OPT_fixit_EQ:
|
2012-11-01 12:30:05 +08:00
|
|
|
Opts.FixItSuffix = A->getValue();
|
2010-04-24 09:30:46 +08:00
|
|
|
// fall-through!
|
2009-12-01 11:16:53 +08:00
|
|
|
case OPT_fixit:
|
|
|
|
Opts.ProgramAction = frontend::FixIt; break;
|
2011-08-26 06:30:56 +08:00
|
|
|
case OPT_emit_module:
|
|
|
|
Opts.ProgramAction = frontend::GenerateModule; break;
|
2009-12-01 11:16:53 +08:00
|
|
|
case OPT_emit_pch:
|
|
|
|
Opts.ProgramAction = frontend::GeneratePCH; break;
|
|
|
|
case OPT_emit_pth:
|
|
|
|
Opts.ProgramAction = frontend::GeneratePTH; break;
|
2010-03-20 03:44:04 +08:00
|
|
|
case OPT_init_only:
|
|
|
|
Opts.ProgramAction = frontend::InitOnly; break;
|
2009-12-01 11:16:53 +08:00
|
|
|
case OPT_fsyntax_only:
|
|
|
|
Opts.ProgramAction = frontend::ParseSyntaxOnly; break;
|
2013-03-28 00:47:18 +08:00
|
|
|
case OPT_module_file_info:
|
|
|
|
Opts.ProgramAction = frontend::ModuleFileInfo; break;
|
2014-02-06 06:21:15 +08:00
|
|
|
case OPT_verify_pch:
|
|
|
|
Opts.ProgramAction = frontend::VerifyPCH; break;
|
2009-12-01 11:16:53 +08:00
|
|
|
case OPT_print_decl_contexts:
|
|
|
|
Opts.ProgramAction = frontend::PrintDeclContext; break;
|
2010-07-21 04:18:03 +08:00
|
|
|
case OPT_print_preamble:
|
|
|
|
Opts.ProgramAction = frontend::PrintPreamble; break;
|
2009-12-01 11:16:53 +08:00
|
|
|
case OPT_E:
|
|
|
|
Opts.ProgramAction = frontend::PrintPreprocessedInput; break;
|
|
|
|
case OPT_rewrite_macros:
|
|
|
|
Opts.ProgramAction = frontend::RewriteMacros; break;
|
|
|
|
case OPT_rewrite_objc:
|
|
|
|
Opts.ProgramAction = frontend::RewriteObjC; break;
|
|
|
|
case OPT_rewrite_test:
|
|
|
|
Opts.ProgramAction = frontend::RewriteTest; break;
|
|
|
|
case OPT_analyze:
|
|
|
|
Opts.ProgramAction = frontend::RunAnalysis; break;
|
2012-03-07 04:06:33 +08:00
|
|
|
case OPT_migrate:
|
|
|
|
Opts.ProgramAction = frontend::MigrateSource; break;
|
2009-12-01 11:16:53 +08:00
|
|
|
case OPT_Eonly:
|
|
|
|
Opts.ProgramAction = frontend::RunPreprocessorOnly; break;
|
|
|
|
}
|
|
|
|
}
|
2010-06-17 00:59:23 +08:00
|
|
|
|
|
|
|
if (const Arg* A = Args.getLastArg(OPT_plugin)) {
|
2015-05-30 03:42:19 +08:00
|
|
|
Opts.Plugins.emplace_back(A->getValue(0));
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.ProgramAction = frontend::PluginAction;
|
2012-11-01 12:30:05 +08:00
|
|
|
Opts.ActionName = A->getValue();
|
2009-12-01 11:16:53 +08:00
|
|
|
}
|
2011-01-26 04:34:14 +08:00
|
|
|
Opts.AddPluginActions = Args.getAllArgValues(OPT_add_plugin);
|
2016-03-15 20:51:40 +08:00
|
|
|
for (const Arg *AA : Args.filtered(OPT_plugin_arg))
|
|
|
|
Opts.PluginArgs[AA->getValue(0)].emplace_back(AA->getValue(1));
|
2011-01-26 04:34:14 +08:00
|
|
|
|
2015-11-04 02:33:07 +08:00
|
|
|
for (const std::string &Arg :
|
|
|
|
Args.getAllArgValues(OPT_ftest_module_file_extension_EQ)) {
|
|
|
|
std::string BlockName;
|
|
|
|
unsigned MajorVersion;
|
|
|
|
unsigned MinorVersion;
|
|
|
|
bool Hashed;
|
|
|
|
std::string UserInfo;
|
|
|
|
if (parseTestModuleFileExtensionArg(Arg, BlockName, MajorVersion,
|
|
|
|
MinorVersion, Hashed, UserInfo)) {
|
|
|
|
Diags.Report(diag::err_test_module_file_extension_format) << Arg;
|
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add the testing module file extension.
|
|
|
|
Opts.ModuleFileExtensions.push_back(
|
|
|
|
new TestModuleFileExtension(BlockName, MajorVersion, MinorVersion,
|
|
|
|
Hashed, UserInfo));
|
|
|
|
}
|
|
|
|
|
2009-12-01 11:16:53 +08:00
|
|
|
if (const Arg *A = Args.getLastArg(OPT_code_completion_at)) {
|
|
|
|
Opts.CodeCompletionAt =
|
2012-11-01 12:30:05 +08:00
|
|
|
ParsedSourceLocation::FromString(A->getValue());
|
2009-12-01 11:16:53 +08:00
|
|
|
if (Opts.CodeCompletionAt.FileName.empty())
|
|
|
|
Diags.Report(diag::err_drv_invalid_value)
|
2012-11-01 12:30:05 +08:00
|
|
|
<< A->getAsString(Args) << A->getValue();
|
2009-12-01 11:16:53 +08:00
|
|
|
}
|
|
|
|
Opts.DisableFree = Args.hasArg(OPT_disable_free);
|
|
|
|
|
2010-05-21 00:54:55 +08:00
|
|
|
Opts.OutputFile = Args.getLastArgValue(OPT_o);
|
|
|
|
Opts.Plugins = Args.getAllArgValues(OPT_load);
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.RelocatablePCH = Args.hasArg(OPT_relocatable_pch);
|
2009-12-03 15:01:58 +08:00
|
|
|
Opts.ShowHelp = Args.hasArg(OPT_help);
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.ShowStats = Args.hasArg(OPT_print_stats);
|
|
|
|
Opts.ShowTimers = Args.hasArg(OPT_ftime_report);
|
2009-12-03 15:01:58 +08:00
|
|
|
Opts.ShowVersion = Args.hasArg(OPT_version);
|
2010-05-21 00:54:55 +08:00
|
|
|
Opts.ASTMergeFiles = Args.getAllArgValues(OPT_ast_merge);
|
|
|
|
Opts.LLVMArgs = Args.getAllArgValues(OPT_mllvm);
|
2010-08-14 01:31:00 +08:00
|
|
|
Opts.FixWhatYouCan = Args.hasArg(OPT_fix_what_you_can);
|
2012-01-26 10:40:48 +08:00
|
|
|
Opts.FixOnlyWarnings = Args.hasArg(OPT_fix_only_warnings);
|
|
|
|
Opts.FixAndRecompile = Args.hasArg(OPT_fixit_recompile);
|
|
|
|
Opts.FixToTemporaries = Args.hasArg(OPT_fixit_to_temp);
|
2014-08-12 06:11:07 +08:00
|
|
|
Opts.ASTDumpDecls = Args.hasArg(OPT_ast_dump);
|
2012-07-27 00:01:23 +08:00
|
|
|
Opts.ASTDumpFilter = Args.getLastArgValue(OPT_ast_dump_filter);
|
2013-06-24 09:45:33 +08:00
|
|
|
Opts.ASTDumpLookups = Args.hasArg(OPT_ast_dump_lookups);
|
2013-01-29 02:38:02 +08:00
|
|
|
Opts.UseGlobalModuleIndex = !Args.hasArg(OPT_fno_modules_global_index);
|
2013-01-25 08:45:27 +08:00
|
|
|
Opts.GenerateGlobalModuleIndex = Opts.UseGlobalModuleIndex;
|
2014-12-06 09:13:41 +08:00
|
|
|
Opts.ModuleMapFiles = Args.getAllArgValues(OPT_fmodule_map_file);
|
2014-10-22 10:05:46 +08:00
|
|
|
Opts.ModuleFiles = Args.getAllArgValues(OPT_fmodule_file);
|
2015-08-14 13:02:58 +08:00
|
|
|
Opts.ModulesEmbedFiles = Args.getAllArgValues(OPT_fmodules_embed_file_EQ);
|
2015-11-24 12:22:21 +08:00
|
|
|
Opts.ModulesEmbedAllFiles = Args.hasArg(OPT_fmodules_embed_all_files);
|
2014-10-22 10:05:46 +08:00
|
|
|
|
2012-07-03 01:35:10 +08:00
|
|
|
Opts.CodeCompleteOpts.IncludeMacros
|
|
|
|
= Args.hasArg(OPT_code_completion_macros);
|
|
|
|
Opts.CodeCompleteOpts.IncludeCodePatterns
|
|
|
|
= Args.hasArg(OPT_code_completion_patterns);
|
|
|
|
Opts.CodeCompleteOpts.IncludeGlobals
|
|
|
|
= !Args.hasArg(OPT_no_code_completion_globals);
|
|
|
|
Opts.CodeCompleteOpts.IncludeBriefComments
|
|
|
|
= Args.hasArg(OPT_code_completion_brief_comments);
|
|
|
|
|
Extend the ExternalASTSource interface to allow the AST source to
provide the layout of records, rather than letting Clang compute
the layout itself. LLDB provides the motivation for this feature:
because various layout-altering attributes (packed, aligned, etc.)
don't get reliably get placed into DWARF, the record layouts computed
by LLDB from the reconstructed records differ from the actual layouts,
and badness occurs. This interface lets the DWARF data drive layout,
so we don't need the attributes preserved to get the answer write.
The testing methodology for this change is fun. I've introduced a
variant of -fdump-record-layouts called -fdump-record-layouts-simple
that always has the simple C format and provides size/alignment/field
offsets. There is also a -cc1 option -foverride-record-layout=<file>
to take the output of -fdump-record-layouts-simple and parse it to
produce a set of overridden layouts, which is introduced into the AST
via a testing-only ExternalASTSource (called
LayoutOverrideSource). Each test contains a number of records to lay
out, which use various layout-changing attributes, and then dumps the
layouts. We then run the test again, using the preprocessor to
eliminate the layout-changing attributes entirely (which would give us
different layouts for the records), but supplying the
previously-computed record layouts. Finally, we diff the layouts
produced from the two runs to be sure that they are identical.
Note that this code makes the assumption that we don't *have* to
provide the offsets of bases or virtual bases to get the layout right,
because the alignment attributes don't affect it. I believe this
assumption holds, but if it does not, we can extend
LayoutOverrideSource to also provide base offset information.
Fixes the Clang side of <rdar://problem/10169539>.
llvm-svn: 149055
2012-01-26 15:55:45 +08:00
|
|
|
Opts.OverrideRecordLayoutsFile
|
|
|
|
= Args.getLastArgValue(OPT_foverride_record_layout_EQ);
|
2015-09-23 01:23:22 +08:00
|
|
|
Opts.AuxTriple =
|
|
|
|
llvm::Triple::normalize(Args.getLastArgValue(OPT_aux_triple));
|
clang-cl: Implement initial limited support for precompiled headers.
In the gcc precompiled header model, one explicitly runs clang with `-x
c++-header` on a .h file to produce a gch file, and then includes the header
with `-include foo.h` and if a .gch file exists for that header it gets used.
This is documented at
http://clang.llvm.org/docs/UsersManual.html#precompiled-headers
cl.exe's model is fairly different, and controlled by the two flags /Yc and
/Yu. A pch file is generated as a side effect of a regular compilation when
/Ycheader.h is passed. While the compilation is running, the compiler keeps
track of #include lines in the main translation unit and writes everything up
to an `#include "header.h"` line into a pch file. Conversely, /Yuheader.h tells
the compiler to skip all code in the main TU up to and including `#include
"header.h"` and instead load header.pch. (It's also possible to use /Yc and /Yu
without an argument, in that case a `#pragma hrdstop` takes the role of
controlling the point where pch ends and real code begins.)
This patch implements limited support for this in that it requires the pch
header to be passed as a /FI force include flag – with this restriction,
it can be implemented almost completely in the driver with fairly small amounts
of code. For /Yu, this is trivial, and for /Yc a separate pch action is added
that runs before the actual compilation. After r261774, the first failing
command makes a compilation stop – this means if the pch fails to build the
main compilation won't run, which is what we want. However, in /fallback builds
we need to run the main compilation even if the pch build fails so that the
main compilation's fallback can run. To achieve this, add a ForceSuccessCommand
that pretends that the pch build always succeeded in /fallback builds (the main
compilation will then fail to open the pch and run the fallback cl.exe
invocation).
If /Yc /Yu are used in a setup that clang-cl doesn't implement yet, clang-cl
will now emit a "not implemented yet; flag ignored" warning that can be
disabled using -Wno-clang-cl-pch.
Since clang-cl doesn't yet serialize some important things (most notably
`pragma comment(lib, ...)`, this feature is disabled by default and only
enabled by an internal driver flag. Once it's more stable, this internal flag
will disappear.
(The default stdafx.h setup passes stdafx.h as explicit argument to /Yc but not
as /FI – instead every single TU has to `#include <stdafx.h>` as first thing it
does. Implementing support for this should be possible with the approach in
this patch with minimal frontend changes by passing a --stop-at / --start-at
flag from the driver to the frontend. This is left for a follow-up. I don't
think we ever want to support `#pragma hdrstop`, and supporting it with this
approach isn't easy: This approach relies on the driver knowing the pch
filename in advance, and `#pragma hdrstop(out.pch)` can set the output
filename, so the driver can't know about it in advance.)
clang-cl now also honors /Fp and puts pch files in the same spot that cl.exe
would put them, but the pch file format is of course incompatible. This has
ramifications on /fallback, so /Yc /Yu aren't passed through to cl.exe in
/fallback builds.
http://reviews.llvm.org/D17695
llvm-svn: 262420
2016-03-02 07:16:44 +08:00
|
|
|
Opts.FindPchSource = Args.getLastArgValue(OPT_find_pch_source_EQ);
|
2015-09-23 01:23:22 +08:00
|
|
|
|
2011-06-16 07:25:17 +08:00
|
|
|
if (const Arg *A = Args.getLastArg(OPT_arcmt_check,
|
2011-07-10 04:00:58 +08:00
|
|
|
OPT_arcmt_modify,
|
|
|
|
OPT_arcmt_migrate)) {
|
2011-06-16 07:25:17 +08:00
|
|
|
switch (A->getOption().getID()) {
|
|
|
|
default:
|
|
|
|
llvm_unreachable("missed a case");
|
|
|
|
case OPT_arcmt_check:
|
|
|
|
Opts.ARCMTAction = FrontendOptions::ARCMT_Check;
|
|
|
|
break;
|
|
|
|
case OPT_arcmt_modify:
|
|
|
|
Opts.ARCMTAction = FrontendOptions::ARCMT_Modify;
|
|
|
|
break;
|
2011-07-10 04:00:58 +08:00
|
|
|
case OPT_arcmt_migrate:
|
|
|
|
Opts.ARCMTAction = FrontendOptions::ARCMT_Migrate;
|
|
|
|
break;
|
2011-06-16 07:25:17 +08:00
|
|
|
}
|
|
|
|
}
|
2012-03-07 04:06:33 +08:00
|
|
|
Opts.MTMigrateDir = Args.getLastArgValue(OPT_mt_migrate_directory);
|
2011-07-20 01:20:03 +08:00
|
|
|
Opts.ARCMTMigrateReportOut
|
|
|
|
= Args.getLastArgValue(OPT_arcmt_migrate_report_output);
|
|
|
|
Opts.ARCMTMigrateEmitARCErrors
|
|
|
|
= Args.hasArg(OPT_arcmt_migrate_emit_arc_errors);
|
2011-06-16 07:25:17 +08:00
|
|
|
|
2012-03-07 04:06:33 +08:00
|
|
|
if (Args.hasArg(OPT_objcmt_migrate_literals))
|
|
|
|
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_Literals;
|
|
|
|
if (Args.hasArg(OPT_objcmt_migrate_subscripting))
|
|
|
|
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_Subscripting;
|
2014-11-01 05:19:45 +08:00
|
|
|
if (Args.hasArg(OPT_objcmt_migrate_property_dot_syntax))
|
|
|
|
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_PropertyDotSyntax;
|
2013-07-10 00:59:14 +08:00
|
|
|
if (Args.hasArg(OPT_objcmt_migrate_property))
|
|
|
|
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_Property;
|
2013-08-29 07:22:46 +08:00
|
|
|
if (Args.hasArg(OPT_objcmt_migrate_readonly_property))
|
|
|
|
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_ReadonlyProperty;
|
2013-10-03 05:32:39 +08:00
|
|
|
if (Args.hasArg(OPT_objcmt_migrate_readwrite_property))
|
|
|
|
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_ReadwriteProperty;
|
2013-10-03 05:58:13 +08:00
|
|
|
if (Args.hasArg(OPT_objcmt_migrate_annotation))
|
|
|
|
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_Annotation;
|
2013-11-06 06:28:30 +08:00
|
|
|
if (Args.hasArg(OPT_objcmt_returns_innerpointer_property))
|
|
|
|
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_ReturnsInnerPointerProperty;
|
2013-10-03 05:58:13 +08:00
|
|
|
if (Args.hasArg(OPT_objcmt_migrate_instancetype))
|
|
|
|
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_Instancetype;
|
|
|
|
if (Args.hasArg(OPT_objcmt_migrate_nsmacros))
|
|
|
|
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_NsMacros;
|
|
|
|
if (Args.hasArg(OPT_objcmt_migrate_protocol_conformance))
|
|
|
|
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_ProtocolConformance;
|
2013-10-10 03:06:08 +08:00
|
|
|
if (Args.hasArg(OPT_objcmt_atomic_property))
|
|
|
|
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_AtomicProperty;
|
2013-11-13 08:08:36 +08:00
|
|
|
if (Args.hasArg(OPT_objcmt_ns_nonatomic_iosonly))
|
|
|
|
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_NsAtomicIOSOnlyProperty;
|
2013-12-11 02:36:49 +08:00
|
|
|
if (Args.hasArg(OPT_objcmt_migrate_designated_init))
|
|
|
|
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_DesignatedInitializer;
|
2013-10-03 05:32:39 +08:00
|
|
|
if (Args.hasArg(OPT_objcmt_migrate_all))
|
|
|
|
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_MigrateDecls;
|
2012-03-07 04:06:33 +08:00
|
|
|
|
2013-12-11 02:36:53 +08:00
|
|
|
Opts.ObjCMTWhiteListPath = Args.getLastArgValue(OPT_objcmt_whitelist_dir_path);
|
2013-11-15 00:33:29 +08:00
|
|
|
|
2012-03-07 04:06:33 +08:00
|
|
|
if (Opts.ARCMTAction != FrontendOptions::ARCMT_None &&
|
|
|
|
Opts.ObjCMTAction != FrontendOptions::ObjCMT_None) {
|
|
|
|
Diags.Report(diag::err_drv_argument_not_allowed_with)
|
|
|
|
<< "ARC migration" << "ObjC migration";
|
|
|
|
}
|
|
|
|
|
2010-06-08 07:22:09 +08:00
|
|
|
InputKind DashX = IK_None;
|
2009-12-01 11:16:53 +08:00
|
|
|
if (const Arg *A = Args.getLastArg(OPT_x)) {
|
2012-11-01 12:30:05 +08:00
|
|
|
DashX = llvm::StringSwitch<InputKind>(A->getValue())
|
2010-06-08 07:22:09 +08:00
|
|
|
.Case("c", IK_C)
|
|
|
|
.Case("cl", IK_OpenCL)
|
2010-12-01 11:15:20 +08:00
|
|
|
.Case("cuda", IK_CUDA)
|
2010-06-08 07:22:09 +08:00
|
|
|
.Case("c++", IK_CXX)
|
|
|
|
.Case("objective-c", IK_ObjC)
|
|
|
|
.Case("objective-c++", IK_ObjCXX)
|
|
|
|
.Case("cpp-output", IK_PreprocessedC)
|
|
|
|
.Case("assembler-with-cpp", IK_Asm)
|
|
|
|
.Case("c++-cpp-output", IK_PreprocessedCXX)
|
2015-03-20 01:32:06 +08:00
|
|
|
.Case("cuda-cpp-output", IK_PreprocessedCuda)
|
2010-06-08 07:22:09 +08:00
|
|
|
.Case("objective-c-cpp-output", IK_PreprocessedObjC)
|
2011-04-09 15:09:31 +08:00
|
|
|
.Case("objc-cpp-output", IK_PreprocessedObjC)
|
2010-06-08 07:22:09 +08:00
|
|
|
.Case("objective-c++-cpp-output", IK_PreprocessedObjCXX)
|
2011-08-14 03:03:50 +08:00
|
|
|
.Case("objc++-cpp-output", IK_PreprocessedObjCXX)
|
2010-06-08 07:22:09 +08:00
|
|
|
.Case("c-header", IK_C)
|
2011-10-10 06:03:19 +08:00
|
|
|
.Case("cl-header", IK_OpenCL)
|
2010-06-08 07:22:09 +08:00
|
|
|
.Case("objective-c-header", IK_ObjC)
|
|
|
|
.Case("c++-header", IK_CXX)
|
|
|
|
.Case("objective-c++-header", IK_ObjCXX)
|
2013-03-28 00:47:18 +08:00
|
|
|
.Cases("ast", "pcm", IK_AST)
|
2010-06-08 07:26:47 +08:00
|
|
|
.Case("ir", IK_LLVM_IR)
|
2010-06-08 07:22:09 +08:00
|
|
|
.Default(IK_None);
|
|
|
|
if (DashX == IK_None)
|
2009-12-01 11:16:53 +08:00
|
|
|
Diags.Report(diag::err_drv_invalid_value)
|
2012-11-01 12:30:05 +08:00
|
|
|
<< A->getAsString(Args) << A->getValue();
|
2009-12-01 11:16:53 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// '-' is the default input if none is given.
|
2010-05-21 00:54:55 +08:00
|
|
|
std::vector<std::string> Inputs = Args.getAllArgValues(OPT_INPUT);
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.Inputs.clear();
|
|
|
|
if (Inputs.empty())
|
|
|
|
Inputs.push_back("-");
|
|
|
|
for (unsigned i = 0, e = Inputs.size(); i != e; ++i) {
|
2010-06-08 07:22:09 +08:00
|
|
|
InputKind IK = DashX;
|
|
|
|
if (IK == IK_None) {
|
2009-12-01 11:16:53 +08:00
|
|
|
IK = FrontendOptions::getInputKindForExtension(
|
2011-07-23 18:55:15 +08:00
|
|
|
StringRef(Inputs[i]).rsplit('.').second);
|
2009-12-01 11:16:53 +08:00
|
|
|
// FIXME: Remove this hack.
|
|
|
|
if (i == 0)
|
|
|
|
DashX = IK;
|
|
|
|
}
|
2015-05-30 03:42:19 +08:00
|
|
|
Opts.Inputs.emplace_back(std::move(Inputs[i]), IK);
|
2009-12-01 11:16:53 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return DashX;
|
|
|
|
}
|
|
|
|
|
2009-12-15 08:06:45 +08:00
|
|
|
std::string CompilerInvocation::GetResourcesPath(const char *Argv0,
|
|
|
|
void *MainAddr) {
|
2014-12-30 05:28:15 +08:00
|
|
|
std::string ClangExecutable =
|
|
|
|
llvm::sys::fs::getMainExecutable(Argv0, MainAddr);
|
2014-12-29 20:09:08 +08:00
|
|
|
StringRef Dir = llvm::sys::path::parent_path(ClangExecutable);
|
|
|
|
|
|
|
|
// Compute the path to the resource directory.
|
|
|
|
StringRef ClangResourceDir(CLANG_RESOURCE_DIR);
|
|
|
|
SmallString<128> P(Dir);
|
2015-08-06 04:06:56 +08:00
|
|
|
if (ClangResourceDir != "")
|
2014-12-29 20:09:08 +08:00
|
|
|
llvm::sys::path::append(P, ClangResourceDir);
|
2015-08-06 04:06:56 +08:00
|
|
|
else
|
|
|
|
llvm::sys::path::append(P, "..", Twine("lib") + CLANG_LIBDIR_SUFFIX,
|
|
|
|
"clang", CLANG_VERSION_STRING);
|
2009-12-01 11:16:53 +08:00
|
|
|
|
|
|
|
return P.str();
|
|
|
|
}
|
|
|
|
|
2009-12-13 11:45:58 +08:00
|
|
|
static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args) {
|
2012-05-01 22:57:16 +08:00
|
|
|
using namespace options;
|
2010-05-21 00:54:55 +08:00
|
|
|
Opts.Sysroot = Args.getLastArgValue(OPT_isysroot, "/");
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.Verbose = Args.hasArg(OPT_v);
|
2011-10-11 04:34:10 +08:00
|
|
|
Opts.UseBuiltinIncludes = !Args.hasArg(OPT_nobuiltininc);
|
2011-10-12 02:20:10 +08:00
|
|
|
Opts.UseStandardSystemIncludes = !Args.hasArg(OPT_nostdsysteminc);
|
2010-03-25 04:13:48 +08:00
|
|
|
Opts.UseStandardCXXIncludes = !Args.hasArg(OPT_nostdincxx);
|
2011-06-22 05:12:29 +08:00
|
|
|
if (const Arg *A = Args.getLastArg(OPT_stdlib_EQ))
|
2012-11-01 12:30:05 +08:00
|
|
|
Opts.UseLibcxx = (strcmp(A->getValue(), "libc++") == 0);
|
2010-05-21 00:54:55 +08:00
|
|
|
Opts.ResourceDir = Args.getLastArgValue(OPT_resource_dir);
|
2013-02-08 03:01:24 +08:00
|
|
|
Opts.ModuleCachePath = Args.getLastArgValue(OPT_fmodules_cache_path);
|
2014-03-03 16:12:05 +08:00
|
|
|
Opts.ModuleUserBuildPath = Args.getLastArgValue(OPT_fmodules_user_build_path);
|
2011-09-14 07:15:45 +08:00
|
|
|
Opts.DisableModuleHash = Args.hasArg(OPT_fdisable_module_hash);
|
2015-06-16 08:08:24 +08:00
|
|
|
Opts.ImplicitModuleMaps = Args.hasArg(OPT_fimplicit_module_maps);
|
2014-12-10 11:09:48 +08:00
|
|
|
Opts.ModuleMapFileHomeIsCwd = Args.hasArg(OPT_fmodule_map_file_home_is_cwd);
|
2013-06-15 01:17:23 +08:00
|
|
|
Opts.ModuleCachePruneInterval =
|
|
|
|
getLastArgIntValue(Args, OPT_fmodules_prune_interval, 7 * 24 * 60 * 60);
|
|
|
|
Opts.ModuleCachePruneAfter =
|
|
|
|
getLastArgIntValue(Args, OPT_fmodules_prune_after, 31 * 24 * 60 * 60);
|
Add an option to allow Clang verify source files for a module only once during
the build
When Clang loads the module, it verifies the user source files that the module
was built from. If any file was changed, the module is rebuilt. There are two
problems with this:
1. correctness: we don't verify system files (there are too many of them, and
stat'ing all of them would take a lot of time);
2. performance: the same module file is verified again and again during a
single build.
This change allows the build system to optimize source file verification. The
idea is based on the fact that while the project is being built, the source
files don't change. This allows us to verify the module only once during a
single build session. The build system passes a flag,
-fbuild-session-timestamp=, to inform Clang of the time when the build started.
The build system also requests to enable this feature by passing
-fmodules-validate-once-per-build-session. If these flags are not passed, the
behavior is not changed. When Clang verifies the module the first time, it
writes out a timestamp file. Then, when Clang loads the module the second
time, it finds a timestamp file, so it can compare the verification timestamp
of the module with the time when the build started. If the verification
timestamp is too old, the module is verified again, and the timestamp file is
updated.
llvm-svn: 201224
2014-02-12 18:33:14 +08:00
|
|
|
Opts.ModulesValidateOncePerBuildSession =
|
|
|
|
Args.hasArg(OPT_fmodules_validate_once_per_build_session);
|
|
|
|
Opts.BuildSessionTimestamp =
|
|
|
|
getLastArgUInt64Value(Args, OPT_fbuild_session_timestamp, 0);
|
2014-03-12 08:06:17 +08:00
|
|
|
Opts.ModulesValidateSystemHeaders =
|
|
|
|
Args.hasArg(OPT_fmodules_validate_system_headers);
|
2015-07-17 09:19:54 +08:00
|
|
|
if (const Arg *A = Args.getLastArg(OPT_fmodule_format_EQ))
|
|
|
|
Opts.ModuleFormat = A->getValue();
|
2014-03-12 08:06:17 +08:00
|
|
|
|
2015-06-09 09:57:17 +08:00
|
|
|
for (const Arg *A : Args.filtered(OPT_fmodules_ignore_macro)) {
|
|
|
|
StringRef MacroDef = A->getValue();
|
2013-02-07 09:18:48 +08:00
|
|
|
Opts.ModulesIgnoreMacros.insert(MacroDef.split('=').first);
|
2013-02-07 08:21:12 +08:00
|
|
|
}
|
|
|
|
|
2011-07-28 12:45:53 +08:00
|
|
|
// Add -I..., -F..., and -index-header-map options in order.
|
|
|
|
bool IsIndexHeaderMap = false;
|
2016-05-07 03:13:55 +08:00
|
|
|
bool IsSysrootSpecified =
|
|
|
|
Args.hasArg(OPT__sysroot_EQ) || Args.hasArg(OPT_isysroot);
|
2015-06-09 09:57:17 +08:00
|
|
|
for (const Arg *A : Args.filtered(OPT_I, OPT_F, OPT_index_header_map)) {
|
|
|
|
if (A->getOption().matches(OPT_index_header_map)) {
|
2011-07-28 12:45:53 +08:00
|
|
|
// -index-header-map applies to the next -I or -F.
|
|
|
|
IsIndexHeaderMap = true;
|
|
|
|
continue;
|
|
|
|
}
|
2015-06-09 09:57:17 +08:00
|
|
|
|
|
|
|
frontend::IncludeDirGroup Group =
|
|
|
|
IsIndexHeaderMap ? frontend::IndexHeaderMap : frontend::Angled;
|
|
|
|
|
2016-05-07 03:13:55 +08:00
|
|
|
bool IsFramework = A->getOption().matches(OPT_F);
|
|
|
|
std::string Path = A->getValue();
|
|
|
|
|
|
|
|
if (IsSysrootSpecified && !IsFramework && A->getValue()[0] == '=') {
|
|
|
|
SmallString<32> Buffer;
|
|
|
|
llvm::sys::path::append(Buffer, Opts.Sysroot,
|
|
|
|
llvm::StringRef(A->getValue()).substr(1));
|
|
|
|
Path = Buffer.str();
|
|
|
|
}
|
|
|
|
|
|
|
|
Opts.AddPath(Path.c_str(), Group, IsFramework,
|
|
|
|
/*IgnoreSysroot*/ true);
|
2011-07-28 12:45:53 +08:00
|
|
|
IsIndexHeaderMap = false;
|
|
|
|
}
|
2009-12-01 11:16:53 +08:00
|
|
|
|
2013-01-25 09:50:34 +08:00
|
|
|
// Add -iprefix/-iwithprefix/-iwithprefixbefore options.
|
2011-07-23 18:55:15 +08:00
|
|
|
StringRef Prefix = ""; // FIXME: This isn't the correct default prefix.
|
2015-06-09 09:57:17 +08:00
|
|
|
for (const Arg *A :
|
|
|
|
Args.filtered(OPT_iprefix, OPT_iwithprefix, OPT_iwithprefixbefore)) {
|
2010-06-12 06:00:13 +08:00
|
|
|
if (A->getOption().matches(OPT_iprefix))
|
2012-11-01 12:30:05 +08:00
|
|
|
Prefix = A->getValue();
|
2010-06-12 06:00:13 +08:00
|
|
|
else if (A->getOption().matches(OPT_iwithprefix))
|
2015-06-09 09:57:17 +08:00
|
|
|
Opts.AddPath(Prefix.str() + A->getValue(), frontend::After, false, true);
|
2009-12-01 11:16:53 +08:00
|
|
|
else
|
2015-06-09 09:57:17 +08:00
|
|
|
Opts.AddPath(Prefix.str() + A->getValue(), frontend::Angled, false, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const Arg *A : Args.filtered(OPT_idirafter))
|
|
|
|
Opts.AddPath(A->getValue(), frontend::After, false, true);
|
|
|
|
for (const Arg *A : Args.filtered(OPT_iquote))
|
|
|
|
Opts.AddPath(A->getValue(), frontend::Quoted, false, true);
|
|
|
|
for (const Arg *A : Args.filtered(OPT_isystem, OPT_iwithsysroot))
|
|
|
|
Opts.AddPath(A->getValue(), frontend::System, false,
|
|
|
|
!A->getOption().matches(OPT_iwithsysroot));
|
|
|
|
for (const Arg *A : Args.filtered(OPT_iframework))
|
|
|
|
Opts.AddPath(A->getValue(), frontend::System, true, true);
|
2011-09-23 05:41:16 +08:00
|
|
|
|
|
|
|
// Add the paths for the various language specific isystem flags.
|
2015-06-09 09:57:17 +08:00
|
|
|
for (const Arg *A : Args.filtered(OPT_c_isystem))
|
|
|
|
Opts.AddPath(A->getValue(), frontend::CSystem, false, true);
|
|
|
|
for (const Arg *A : Args.filtered(OPT_cxx_isystem))
|
|
|
|
Opts.AddPath(A->getValue(), frontend::CXXSystem, false, true);
|
|
|
|
for (const Arg *A : Args.filtered(OPT_objc_isystem))
|
|
|
|
Opts.AddPath(A->getValue(), frontend::ObjCSystem, false,true);
|
|
|
|
for (const Arg *A : Args.filtered(OPT_objcxx_isystem))
|
|
|
|
Opts.AddPath(A->getValue(), frontend::ObjCXXSystem, false, true);
|
2011-11-05 16:30:29 +08:00
|
|
|
|
|
|
|
// Add the internal paths from a driver that detects standard include paths.
|
2015-06-09 09:57:17 +08:00
|
|
|
for (const Arg *A :
|
|
|
|
Args.filtered(OPT_internal_isystem, OPT_internal_externc_isystem)) {
|
2013-01-30 08:19:24 +08:00
|
|
|
frontend::IncludeDirGroup Group = frontend::System;
|
2015-06-09 09:57:17 +08:00
|
|
|
if (A->getOption().matches(OPT_internal_externc_isystem))
|
2013-01-30 08:19:24 +08:00
|
|
|
Group = frontend::ExternCSystem;
|
2015-06-09 09:57:17 +08:00
|
|
|
Opts.AddPath(A->getValue(), Group, false, true);
|
2013-01-30 08:19:24 +08:00
|
|
|
}
|
2012-06-14 04:27:03 +08:00
|
|
|
|
|
|
|
// Add the path prefixes which are implicitly treated as being system headers.
|
2015-06-09 09:57:17 +08:00
|
|
|
for (const Arg *A :
|
|
|
|
Args.filtered(OPT_system_header_prefix, OPT_no_system_header_prefix))
|
2014-03-26 09:39:59 +08:00
|
|
|
Opts.AddSystemHeaderPrefix(
|
2015-06-09 09:57:17 +08:00
|
|
|
A->getValue(), A->getOption().matches(OPT_system_header_prefix));
|
2014-02-26 02:23:47 +08:00
|
|
|
|
2015-06-09 09:57:17 +08:00
|
|
|
for (const Arg *A : Args.filtered(OPT_ivfsoverlay))
|
|
|
|
Opts.AddVFSOverlayFile(A->getValue());
|
2009-12-01 11:16:53 +08:00
|
|
|
}
|
|
|
|
|
2010-12-04 09:50:27 +08:00
|
|
|
void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK,
|
2016-04-28 03:53:03 +08:00
|
|
|
const llvm::Triple &T,
|
2010-12-04 09:50:27 +08:00
|
|
|
LangStandard::Kind LangStd) {
|
2011-04-15 13:22:18 +08:00
|
|
|
// Set some properties which depend solely on the input kind; it would be nice
|
2009-12-01 11:16:53 +08:00
|
|
|
// to move these to the language standard, and have the driver resolve the
|
|
|
|
// input kind + language standard.
|
2010-06-08 07:22:09 +08:00
|
|
|
if (IK == IK_Asm) {
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.AsmPreprocessor = 1;
|
2010-06-08 07:22:09 +08:00
|
|
|
} else if (IK == IK_ObjC ||
|
|
|
|
IK == IK_ObjCXX ||
|
|
|
|
IK == IK_PreprocessedObjC ||
|
|
|
|
IK == IK_PreprocessedObjCXX) {
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.ObjC1 = Opts.ObjC2 = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (LangStd == LangStandard::lang_unspecified) {
|
|
|
|
// Based on the base language, pick one.
|
|
|
|
switch (IK) {
|
2010-06-08 07:22:09 +08:00
|
|
|
case IK_None:
|
|
|
|
case IK_AST:
|
2010-06-08 07:26:47 +08:00
|
|
|
case IK_LLVM_IR:
|
2011-09-23 13:06:16 +08:00
|
|
|
llvm_unreachable("Invalid input kind!");
|
2010-06-08 07:22:09 +08:00
|
|
|
case IK_OpenCL:
|
2009-12-01 11:16:53 +08:00
|
|
|
LangStd = LangStandard::lang_opencl;
|
|
|
|
break;
|
2010-12-01 11:15:20 +08:00
|
|
|
case IK_CUDA:
|
2015-03-20 01:32:06 +08:00
|
|
|
case IK_PreprocessedCuda:
|
2010-12-01 11:15:20 +08:00
|
|
|
LangStd = LangStandard::lang_cuda;
|
|
|
|
break;
|
2010-06-08 07:22:09 +08:00
|
|
|
case IK_Asm:
|
|
|
|
case IK_C:
|
|
|
|
case IK_PreprocessedC:
|
|
|
|
case IK_ObjC:
|
|
|
|
case IK_PreprocessedObjC:
|
2016-04-28 03:53:03 +08:00
|
|
|
// The PS4 uses C99 as the default C standard.
|
|
|
|
if (T.isPS4())
|
|
|
|
LangStd = LangStandard::lang_gnu99;
|
|
|
|
else
|
|
|
|
LangStd = LangStandard::lang_gnu11;
|
2009-12-01 11:16:53 +08:00
|
|
|
break;
|
2010-06-08 07:22:09 +08:00
|
|
|
case IK_CXX:
|
|
|
|
case IK_PreprocessedCXX:
|
|
|
|
case IK_ObjCXX:
|
|
|
|
case IK_PreprocessedObjCXX:
|
2009-12-01 11:16:53 +08:00
|
|
|
LangStd = LangStandard::lang_gnucxx98;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
|
2012-11-11 15:02:14 +08:00
|
|
|
Opts.LineComment = Std.hasLineComments();
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.C99 = Std.isC99();
|
2011-12-24 01:00:35 +08:00
|
|
|
Opts.C11 = Std.isC11();
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.CPlusPlus = Std.isCPlusPlus();
|
2013-01-02 19:42:31 +08:00
|
|
|
Opts.CPlusPlus11 = Std.isCPlusPlus11();
|
2014-08-19 23:55:55 +08:00
|
|
|
Opts.CPlusPlus14 = Std.isCPlusPlus14();
|
2014-06-16 23:16:56 +08:00
|
|
|
Opts.CPlusPlus1z = Std.isCPlusPlus1z();
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.Digraphs = Std.hasDigraphs();
|
|
|
|
Opts.GNUMode = Std.isGNUMode();
|
2015-05-14 06:07:22 +08:00
|
|
|
Opts.GNUInline = Std.isC89();
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.HexFloats = Std.hasHexFloats();
|
|
|
|
Opts.ImplicitInt = Std.hasImplicitInt();
|
|
|
|
|
2012-06-19 06:55:02 +08:00
|
|
|
// Set OpenCL Version.
|
2014-05-30 00:39:42 +08:00
|
|
|
Opts.OpenCL = LangStd == LangStandard::lang_opencl || IK == IK_OpenCL;
|
|
|
|
if (LangStd == LangStandard::lang_opencl)
|
2012-06-19 06:55:02 +08:00
|
|
|
Opts.OpenCLVersion = 100;
|
2014-05-30 00:39:42 +08:00
|
|
|
else if (LangStd == LangStandard::lang_opencl11)
|
2014-11-21 03:25:00 +08:00
|
|
|
Opts.OpenCLVersion = 110;
|
2014-05-30 00:39:42 +08:00
|
|
|
else if (LangStd == LangStandard::lang_opencl12)
|
2012-06-19 06:55:02 +08:00
|
|
|
Opts.OpenCLVersion = 120;
|
2014-11-21 03:25:00 +08:00
|
|
|
else if (LangStd == LangStandard::lang_opencl20)
|
|
|
|
Opts.OpenCLVersion = 200;
|
|
|
|
|
2012-06-19 06:55:02 +08:00
|
|
|
// OpenCL has some additional defaults.
|
|
|
|
if (Opts.OpenCL) {
|
2011-09-22 02:28:29 +08:00
|
|
|
Opts.AltiVec = 0;
|
2015-07-30 22:08:36 +08:00
|
|
|
Opts.ZVector = 0;
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.CXXOperatorNames = 1;
|
2011-09-22 02:28:29 +08:00
|
|
|
Opts.LaxVectorConversions = 0;
|
2015-11-17 23:40:10 +08:00
|
|
|
Opts.DefaultFPContract = 1;
|
2013-01-23 19:56:20 +08:00
|
|
|
Opts.NativeHalfType = 1;
|
2016-03-19 00:58:36 +08:00
|
|
|
Opts.NativeHalfArgsAndReturns = 1;
|
2009-12-01 11:16:53 +08:00
|
|
|
}
|
|
|
|
|
2015-03-20 01:32:06 +08:00
|
|
|
Opts.CUDA = IK == IK_CUDA || IK == IK_PreprocessedCuda ||
|
|
|
|
LangStd == LangStandard::lang_cuda;
|
2010-12-01 11:15:20 +08:00
|
|
|
|
2009-12-01 11:16:53 +08:00
|
|
|
// OpenCL and C++ both have bool, true, false keywords.
|
|
|
|
Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
|
|
|
|
|
2014-03-19 01:55:18 +08:00
|
|
|
// OpenCL has half keyword
|
|
|
|
Opts.Half = Opts.OpenCL;
|
|
|
|
|
2012-09-06 01:30:57 +08:00
|
|
|
// C++ has wchar_t keyword.
|
|
|
|
Opts.WChar = Opts.CPlusPlus;
|
|
|
|
|
2010-12-04 09:50:27 +08:00
|
|
|
Opts.GNUKeywords = Opts.GNUMode;
|
|
|
|
Opts.CXXOperatorNames = Opts.CPlusPlus;
|
|
|
|
|
|
|
|
Opts.DollarIdents = !Opts.AsmPreprocessor;
|
|
|
|
}
|
|
|
|
|
2013-02-19 09:57:35 +08:00
|
|
|
/// Attempt to parse a visibility value out of the given argument.
|
|
|
|
static Visibility parseVisibility(Arg *arg, ArgList &args,
|
|
|
|
DiagnosticsEngine &diags) {
|
|
|
|
StringRef value = arg->getValue();
|
|
|
|
if (value == "default") {
|
|
|
|
return DefaultVisibility;
|
2015-10-22 06:01:02 +08:00
|
|
|
} else if (value == "hidden" || value == "internal") {
|
2013-02-19 09:57:35 +08:00
|
|
|
return HiddenVisibility;
|
|
|
|
} else if (value == "protected") {
|
|
|
|
// FIXME: diagnose if target does not support protected visibility
|
|
|
|
return ProtectedVisibility;
|
|
|
|
}
|
|
|
|
|
|
|
|
diags.Report(diag::err_drv_invalid_value)
|
|
|
|
<< arg->getAsString(args) << value;
|
|
|
|
return DefaultVisibility;
|
|
|
|
}
|
|
|
|
|
2010-12-04 09:50:27 +08:00
|
|
|
static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
|
2016-02-08 23:59:20 +08:00
|
|
|
const TargetOptions &TargetOpts,
|
2011-09-26 07:23:43 +08:00
|
|
|
DiagnosticsEngine &Diags) {
|
2010-12-04 09:50:27 +08:00
|
|
|
// FIXME: Cleanup per-file based stuff.
|
|
|
|
LangStandard::Kind LangStd = LangStandard::lang_unspecified;
|
|
|
|
if (const Arg *A = Args.getLastArg(OPT_std_EQ)) {
|
2012-11-01 12:30:05 +08:00
|
|
|
LangStd = llvm::StringSwitch<LangStandard::Kind>(A->getValue())
|
2010-12-04 09:50:27 +08:00
|
|
|
#define LANGSTANDARD(id, name, desc, features) \
|
|
|
|
.Case(name, LangStandard::lang_##id)
|
|
|
|
#include "clang/Frontend/LangStandards.def"
|
|
|
|
.Default(LangStandard::lang_unspecified);
|
|
|
|
if (LangStd == LangStandard::lang_unspecified)
|
|
|
|
Diags.Report(diag::err_drv_invalid_value)
|
2012-11-01 12:30:05 +08:00
|
|
|
<< A->getAsString(Args) << A->getValue();
|
2011-05-03 03:24:53 +08:00
|
|
|
else {
|
2013-12-06 00:25:25 +08:00
|
|
|
// Valid standard, check to make sure language and standard are
|
|
|
|
// compatible.
|
2011-05-03 03:24:53 +08:00
|
|
|
const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
|
|
|
|
switch (IK) {
|
|
|
|
case IK_C:
|
|
|
|
case IK_ObjC:
|
|
|
|
case IK_PreprocessedC:
|
|
|
|
case IK_PreprocessedObjC:
|
|
|
|
if (!(Std.isC89() || Std.isC99()))
|
|
|
|
Diags.Report(diag::err_drv_argument_not_allowed_with)
|
|
|
|
<< A->getAsString(Args) << "C/ObjC";
|
|
|
|
break;
|
|
|
|
case IK_CXX:
|
|
|
|
case IK_ObjCXX:
|
|
|
|
case IK_PreprocessedCXX:
|
|
|
|
case IK_PreprocessedObjCXX:
|
|
|
|
if (!Std.isCPlusPlus())
|
|
|
|
Diags.Report(diag::err_drv_argument_not_allowed_with)
|
|
|
|
<< A->getAsString(Args) << "C++/ObjC++";
|
|
|
|
break;
|
|
|
|
case IK_OpenCL:
|
2016-04-27 03:25:46 +08:00
|
|
|
Diags.Report(diag::err_drv_argument_not_allowed_with)
|
|
|
|
<< A->getAsString(Args) << "OpenCL";
|
2011-05-03 03:24:53 +08:00
|
|
|
break;
|
|
|
|
case IK_CUDA:
|
2015-03-20 01:32:06 +08:00
|
|
|
case IK_PreprocessedCuda:
|
2011-05-03 03:24:53 +08:00
|
|
|
if (!Std.isCPlusPlus())
|
|
|
|
Diags.Report(diag::err_drv_argument_not_allowed_with)
|
|
|
|
<< A->getAsString(Args) << "CUDA";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2010-12-04 09:50:27 +08:00
|
|
|
}
|
|
|
|
|
2012-06-20 07:09:52 +08:00
|
|
|
// -cl-std only applies for OpenCL language standards.
|
|
|
|
// Override the -std option in this case.
|
2010-12-04 09:51:40 +08:00
|
|
|
if (const Arg *A = Args.getLastArg(OPT_cl_std_EQ)) {
|
2012-06-20 07:09:52 +08:00
|
|
|
LangStandard::Kind OpenCLLangStd
|
2012-11-01 12:30:05 +08:00
|
|
|
= llvm::StringSwitch<LangStandard::Kind>(A->getValue())
|
2012-06-20 07:09:52 +08:00
|
|
|
.Case("CL", LangStandard::lang_opencl)
|
|
|
|
.Case("CL1.1", LangStandard::lang_opencl11)
|
|
|
|
.Case("CL1.2", LangStandard::lang_opencl12)
|
2014-11-21 03:25:00 +08:00
|
|
|
.Case("CL2.0", LangStandard::lang_opencl20)
|
2012-06-20 07:09:52 +08:00
|
|
|
.Default(LangStandard::lang_unspecified);
|
2015-08-05 23:08:53 +08:00
|
|
|
|
2012-06-20 07:09:52 +08:00
|
|
|
if (OpenCLLangStd == LangStandard::lang_unspecified) {
|
2010-12-04 09:51:40 +08:00
|
|
|
Diags.Report(diag::err_drv_invalid_value)
|
2012-11-01 12:30:05 +08:00
|
|
|
<< A->getAsString(Args) << A->getValue();
|
2010-12-04 09:51:40 +08:00
|
|
|
}
|
2012-06-20 07:09:52 +08:00
|
|
|
else
|
|
|
|
LangStd = OpenCLLangStd;
|
2010-12-04 09:51:40 +08:00
|
|
|
}
|
2015-08-05 23:08:53 +08:00
|
|
|
|
2016-04-28 03:53:03 +08:00
|
|
|
llvm::Triple T(TargetOpts.Triple);
|
|
|
|
CompilerInvocation::setLangDefaults(Opts, IK, T, LangStd);
|
2010-12-04 09:50:27 +08:00
|
|
|
|
2010-04-18 04:17:31 +08:00
|
|
|
// We abuse '-f[no-]gnu-keywords' to force overriding all GNU-extension
|
|
|
|
// keywords. This behavior is provided by GCC's poorly named '-fasm' flag,
|
|
|
|
// while a subset (the non-C++ GNU keywords) is provided by GCC's
|
|
|
|
// '-fgnu-keywords'. Clang conflates the two for simplicity under the single
|
|
|
|
// name, as it doesn't seem a useful distinction.
|
|
|
|
Opts.GNUKeywords = Args.hasFlag(OPT_fgnu_keywords, OPT_fno_gnu_keywords,
|
2010-12-04 09:50:27 +08:00
|
|
|
Opts.GNUKeywords);
|
2010-04-18 04:17:31 +08:00
|
|
|
|
2010-12-04 09:50:27 +08:00
|
|
|
if (Args.hasArg(OPT_fno_operator_names))
|
|
|
|
Opts.CXXOperatorNames = 0;
|
2009-12-01 11:16:53 +08:00
|
|
|
|
2014-12-04 05:53:36 +08:00
|
|
|
if (Args.hasArg(OPT_fcuda_is_device))
|
|
|
|
Opts.CUDAIsDevice = 1;
|
|
|
|
|
2016-01-27 01:47:20 +08:00
|
|
|
if (Args.hasArg(OPT_fcuda_allow_variadic_functions))
|
|
|
|
Opts.CUDAAllowVariadicFunctions = 1;
|
|
|
|
|
2016-03-31 07:30:21 +08:00
|
|
|
if (Args.hasArg(OPT_fno_cuda_host_device_constexpr))
|
|
|
|
Opts.CUDAHostDeviceConstexpr = 0;
|
|
|
|
|
2016-04-06 02:26:20 +08:00
|
|
|
if (Opts.CUDAIsDevice && Args.hasArg(OPT_fcuda_flush_denormals_to_zero))
|
|
|
|
Opts.CUDADeviceFlushDenormalsToZero = 1;
|
|
|
|
|
2016-05-24 04:19:56 +08:00
|
|
|
if (Opts.CUDAIsDevice && Args.hasArg(OPT_fcuda_approx_transcendentals))
|
|
|
|
Opts.CUDADeviceApproxTranscendentals = 1;
|
|
|
|
|
2011-06-16 07:02:42 +08:00
|
|
|
if (Opts.ObjC1) {
|
2012-06-20 14:18:46 +08:00
|
|
|
if (Arg *arg = Args.getLastArg(OPT_fobjc_runtime_EQ)) {
|
2012-11-01 12:30:05 +08:00
|
|
|
StringRef value = arg->getValue();
|
2012-06-20 14:18:46 +08:00
|
|
|
if (Opts.ObjCRuntime.tryParse(value))
|
|
|
|
Diags.Report(diag::err_drv_unknown_objc_runtime) << value;
|
|
|
|
}
|
|
|
|
|
2011-06-16 07:02:42 +08:00
|
|
|
if (Args.hasArg(OPT_fobjc_gc_only))
|
2011-09-14 01:21:33 +08:00
|
|
|
Opts.setGC(LangOptions::GCOnly);
|
2011-06-16 07:02:42 +08:00
|
|
|
else if (Args.hasArg(OPT_fobjc_gc))
|
2011-09-14 01:21:33 +08:00
|
|
|
Opts.setGC(LangOptions::HybridGC);
|
2011-06-16 07:02:42 +08:00
|
|
|
else if (Args.hasArg(OPT_fobjc_arc)) {
|
|
|
|
Opts.ObjCAutoRefCount = 1;
|
2012-08-21 10:47:43 +08:00
|
|
|
if (!Opts.ObjCRuntime.allowsARC())
|
|
|
|
Diags.Report(diag::err_arc_unsupported_on_runtime);
|
Define weak and __weak to mean ARC-style weak references, even in MRC.
Previously, __weak was silently accepted and ignored in MRC mode.
That makes this a potentially source-breaking change that we have to
roll out cautiously. Accordingly, for the time being, actual support
for __weak references in MRC is experimental, and the compiler will
reject attempts to actually form such references. The intent is to
eventually enable the feature by default in all non-GC modes.
(It is, of course, incompatible with ObjC GC's interpretation of
__weak.)
If you like, you can enable this feature with
-Xclang -fobjc-weak
but like any -Xclang option, this option may be removed at any point,
e.g. if/when it is eventually enabled by default.
This patch also enables the use of the ARC __unsafe_unretained qualifier
in MRC. Unlike __weak, this is being enabled immediately. Since
variables are essentially __unsafe_unretained by default in MRC,
the only practical uses are (1) communication and (2) changing the
default behavior of by-value block capture.
As an implementation matter, this means that the ObjC ownership
qualifiers may appear in any ObjC language mode, and so this patch
removes a number of checks for getLangOpts().ObjCAutoRefCount
that were guarding the processing of these qualifiers. I don't
expect this to be a significant drain on performance; it may even
be faster to just check for these qualifiers directly on a type
(since it's probably in a register anyway) than to do N dependent
loads to grab the LangOptions.
rdar://9674298
llvm-svn: 251041
2015-10-23 02:38:17 +08:00
|
|
|
}
|
2012-08-21 10:47:43 +08:00
|
|
|
|
Define weak and __weak to mean ARC-style weak references, even in MRC.
Previously, __weak was silently accepted and ignored in MRC mode.
That makes this a potentially source-breaking change that we have to
roll out cautiously. Accordingly, for the time being, actual support
for __weak references in MRC is experimental, and the compiler will
reject attempts to actually form such references. The intent is to
eventually enable the feature by default in all non-GC modes.
(It is, of course, incompatible with ObjC GC's interpretation of
__weak.)
If you like, you can enable this feature with
-Xclang -fobjc-weak
but like any -Xclang option, this option may be removed at any point,
e.g. if/when it is eventually enabled by default.
This patch also enables the use of the ARC __unsafe_unretained qualifier
in MRC. Unlike __weak, this is being enabled immediately. Since
variables are essentially __unsafe_unretained by default in MRC,
the only practical uses are (1) communication and (2) changing the
default behavior of by-value block capture.
As an implementation matter, this means that the ObjC ownership
qualifiers may appear in any ObjC language mode, and so this patch
removes a number of checks for getLangOpts().ObjCAutoRefCount
that were guarding the processing of these qualifiers. I don't
expect this to be a significant drain on performance; it may even
be faster to just check for these qualifiers directly on a type
(since it's probably in a register anyway) than to do N dependent
loads to grab the LangOptions.
rdar://9674298
llvm-svn: 251041
2015-10-23 02:38:17 +08:00
|
|
|
// ObjCWeakRuntime tracks whether the runtime supports __weak, not
|
|
|
|
// whether the feature is actually enabled. This is predominantly
|
|
|
|
// determined by -fobjc-runtime, but we allow it to be overridden
|
|
|
|
// from the command line for testing purposes.
|
|
|
|
if (Args.hasArg(OPT_fobjc_runtime_has_weak))
|
|
|
|
Opts.ObjCWeakRuntime = 1;
|
|
|
|
else
|
|
|
|
Opts.ObjCWeakRuntime = Opts.ObjCRuntime.allowsWeak();
|
|
|
|
|
|
|
|
// ObjCWeak determines whether __weak is actually enabled.
|
2015-11-06 03:19:56 +08:00
|
|
|
// Note that we allow -fno-objc-weak to disable this even in ARC mode.
|
|
|
|
if (auto weakArg = Args.getLastArg(OPT_fobjc_weak, OPT_fno_objc_weak)) {
|
|
|
|
if (!weakArg->getOption().matches(OPT_fobjc_weak)) {
|
|
|
|
assert(!Opts.ObjCWeak);
|
|
|
|
} else if (Opts.getGC() != LangOptions::NonGC) {
|
Define weak and __weak to mean ARC-style weak references, even in MRC.
Previously, __weak was silently accepted and ignored in MRC mode.
That makes this a potentially source-breaking change that we have to
roll out cautiously. Accordingly, for the time being, actual support
for __weak references in MRC is experimental, and the compiler will
reject attempts to actually form such references. The intent is to
eventually enable the feature by default in all non-GC modes.
(It is, of course, incompatible with ObjC GC's interpretation of
__weak.)
If you like, you can enable this feature with
-Xclang -fobjc-weak
but like any -Xclang option, this option may be removed at any point,
e.g. if/when it is eventually enabled by default.
This patch also enables the use of the ARC __unsafe_unretained qualifier
in MRC. Unlike __weak, this is being enabled immediately. Since
variables are essentially __unsafe_unretained by default in MRC,
the only practical uses are (1) communication and (2) changing the
default behavior of by-value block capture.
As an implementation matter, this means that the ObjC ownership
qualifiers may appear in any ObjC language mode, and so this patch
removes a number of checks for getLangOpts().ObjCAutoRefCount
that were guarding the processing of these qualifiers. I don't
expect this to be a significant drain on performance; it may even
be faster to just check for these qualifiers directly on a type
(since it's probably in a register anyway) than to do N dependent
loads to grab the LangOptions.
rdar://9674298
llvm-svn: 251041
2015-10-23 02:38:17 +08:00
|
|
|
Diags.Report(diag::err_objc_weak_with_gc);
|
2015-11-06 03:19:56 +08:00
|
|
|
} else if (!Opts.ObjCWeakRuntime) {
|
Define weak and __weak to mean ARC-style weak references, even in MRC.
Previously, __weak was silently accepted and ignored in MRC mode.
That makes this a potentially source-breaking change that we have to
roll out cautiously. Accordingly, for the time being, actual support
for __weak references in MRC is experimental, and the compiler will
reject attempts to actually form such references. The intent is to
eventually enable the feature by default in all non-GC modes.
(It is, of course, incompatible with ObjC GC's interpretation of
__weak.)
If you like, you can enable this feature with
-Xclang -fobjc-weak
but like any -Xclang option, this option may be removed at any point,
e.g. if/when it is eventually enabled by default.
This patch also enables the use of the ARC __unsafe_unretained qualifier
in MRC. Unlike __weak, this is being enabled immediately. Since
variables are essentially __unsafe_unretained by default in MRC,
the only practical uses are (1) communication and (2) changing the
default behavior of by-value block capture.
As an implementation matter, this means that the ObjC ownership
qualifiers may appear in any ObjC language mode, and so this patch
removes a number of checks for getLangOpts().ObjCAutoRefCount
that were guarding the processing of these qualifiers. I don't
expect this to be a significant drain on performance; it may even
be faster to just check for these qualifiers directly on a type
(since it's probably in a register anyway) than to do N dependent
loads to grab the LangOptions.
rdar://9674298
llvm-svn: 251041
2015-10-23 02:38:17 +08:00
|
|
|
Diags.Report(diag::err_objc_weak_unsupported);
|
2015-11-06 03:19:56 +08:00
|
|
|
} else {
|
|
|
|
Opts.ObjCWeak = 1;
|
Define weak and __weak to mean ARC-style weak references, even in MRC.
Previously, __weak was silently accepted and ignored in MRC mode.
That makes this a potentially source-breaking change that we have to
roll out cautiously. Accordingly, for the time being, actual support
for __weak references in MRC is experimental, and the compiler will
reject attempts to actually form such references. The intent is to
eventually enable the feature by default in all non-GC modes.
(It is, of course, incompatible with ObjC GC's interpretation of
__weak.)
If you like, you can enable this feature with
-Xclang -fobjc-weak
but like any -Xclang option, this option may be removed at any point,
e.g. if/when it is eventually enabled by default.
This patch also enables the use of the ARC __unsafe_unretained qualifier
in MRC. Unlike __weak, this is being enabled immediately. Since
variables are essentially __unsafe_unretained by default in MRC,
the only practical uses are (1) communication and (2) changing the
default behavior of by-value block capture.
As an implementation matter, this means that the ObjC ownership
qualifiers may appear in any ObjC language mode, and so this patch
removes a number of checks for getLangOpts().ObjCAutoRefCount
that were guarding the processing of these qualifiers. I don't
expect this to be a significant drain on performance; it may even
be faster to just check for these qualifiers directly on a type
(since it's probably in a register anyway) than to do N dependent
loads to grab the LangOptions.
rdar://9674298
llvm-svn: 251041
2015-10-23 02:38:17 +08:00
|
|
|
}
|
2015-11-06 03:19:56 +08:00
|
|
|
} else if (Opts.ObjCAutoRefCount) {
|
|
|
|
Opts.ObjCWeak = Opts.ObjCWeakRuntime;
|
2011-06-16 07:02:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (Args.hasArg(OPT_fno_objc_infer_related_result_type))
|
|
|
|
Opts.ObjCInferRelatedResultType = 0;
|
2015-08-05 23:08:53 +08:00
|
|
|
|
2013-11-02 05:58:17 +08:00
|
|
|
if (Args.hasArg(OPT_fobjc_subscripting_legacy_runtime))
|
|
|
|
Opts.ObjCSubscriptingLegacyRuntime =
|
|
|
|
(Opts.ObjCRuntime.getKind() == ObjCRuntime::FragileMacOSX);
|
2011-06-16 07:02:42 +08:00
|
|
|
}
|
2015-08-05 23:08:53 +08:00
|
|
|
|
2015-05-14 06:07:22 +08:00
|
|
|
if (Args.hasArg(OPT_fgnu89_inline)) {
|
|
|
|
if (Opts.CPlusPlus)
|
|
|
|
Diags.Report(diag::err_drv_argument_not_allowed_with) << "-fgnu89-inline"
|
|
|
|
<< "C++/ObjC++";
|
|
|
|
else
|
|
|
|
Opts.GNUInline = 1;
|
|
|
|
}
|
2011-06-03 00:13:27 +08:00
|
|
|
|
2011-02-04 08:01:24 +08:00
|
|
|
if (Args.hasArg(OPT_fapple_kext)) {
|
|
|
|
if (!Opts.CPlusPlus)
|
|
|
|
Diags.Report(diag::warn_c_kext);
|
|
|
|
else
|
|
|
|
Opts.AppleKext = 1;
|
|
|
|
}
|
|
|
|
|
2009-12-01 11:16:53 +08:00
|
|
|
if (Args.hasArg(OPT_print_ivar_layout))
|
|
|
|
Opts.ObjCGCBitmapPrint = 1;
|
2010-04-23 04:26:39 +08:00
|
|
|
if (Args.hasArg(OPT_fno_constant_cfstrings))
|
|
|
|
Opts.NoConstantCFStrings = 1;
|
2009-12-01 11:16:53 +08:00
|
|
|
|
|
|
|
if (Args.hasArg(OPT_faltivec))
|
|
|
|
Opts.AltiVec = 1;
|
|
|
|
|
2015-07-30 22:08:36 +08:00
|
|
|
if (Args.hasArg(OPT_fzvector))
|
|
|
|
Opts.ZVector = 1;
|
|
|
|
|
2009-12-01 11:16:53 +08:00
|
|
|
if (Args.hasArg(OPT_pthread))
|
|
|
|
Opts.POSIXThreads = 1;
|
|
|
|
|
2013-02-19 09:57:35 +08:00
|
|
|
// The value-visibility mode defaults to "default".
|
|
|
|
if (Arg *visOpt = Args.getLastArg(OPT_fvisibility)) {
|
|
|
|
Opts.setValueVisibilityMode(parseVisibility(visOpt, Args, Diags));
|
|
|
|
} else {
|
|
|
|
Opts.setValueVisibilityMode(DefaultVisibility);
|
|
|
|
}
|
|
|
|
|
|
|
|
// The type-visibility mode defaults to the value-visibility mode.
|
|
|
|
if (Arg *typeVisOpt = Args.getLastArg(OPT_ftype_visibility)) {
|
|
|
|
Opts.setTypeVisibilityMode(parseVisibility(typeVisOpt, Args, Diags));
|
|
|
|
} else {
|
|
|
|
Opts.setTypeVisibilityMode(Opts.getValueVisibilityMode());
|
|
|
|
}
|
2009-12-01 11:16:53 +08:00
|
|
|
|
2010-06-16 01:05:35 +08:00
|
|
|
if (Args.hasArg(OPT_fvisibility_inlines_hidden))
|
|
|
|
Opts.InlineVisibilityHidden = 1;
|
2010-10-21 11:16:25 +08:00
|
|
|
|
2010-09-18 02:29:54 +08:00
|
|
|
if (Args.hasArg(OPT_ftrapv)) {
|
2010-10-21 11:16:25 +08:00
|
|
|
Opts.setSignedOverflowBehavior(LangOptions::SOB_Trapping);
|
2010-09-18 02:29:54 +08:00
|
|
|
// Set the handler, if one is specified.
|
|
|
|
Opts.OverflowHandler =
|
|
|
|
Args.getLastArgValue(OPT_ftrapv_handler);
|
|
|
|
}
|
2010-06-27 05:25:03 +08:00
|
|
|
else if (Args.hasArg(OPT_fwrapv))
|
2010-10-21 11:16:25 +08:00
|
|
|
Opts.setSignedOverflowBehavior(LangOptions::SOB_Defined);
|
2009-12-01 11:16:53 +08:00
|
|
|
|
2014-12-23 02:35:03 +08:00
|
|
|
Opts.MSVCCompat = Args.hasArg(OPT_fms_compatibility);
|
|
|
|
Opts.MicrosoftExt = Opts.MSVCCompat || Args.hasArg(OPT_fms_extensions);
|
|
|
|
Opts.AsmBlocks = Args.hasArg(OPT_fasm_blocks) || Opts.MicrosoftExt;
|
2015-03-22 16:39:22 +08:00
|
|
|
Opts.MSCompatibilityVersion = 0;
|
|
|
|
if (const Arg *A = Args.getLastArg(OPT_fms_compatibility_version)) {
|
|
|
|
VersionTuple VT;
|
|
|
|
if (VT.tryParse(A->getValue()))
|
|
|
|
Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
|
|
|
|
<< A->getValue();
|
|
|
|
Opts.MSCompatibilityVersion = VT.getMajor() * 10000000 +
|
|
|
|
VT.getMinor().getValueOr(0) * 100000 +
|
|
|
|
VT.getSubminor().getValueOr(0);
|
|
|
|
}
|
2014-12-23 02:35:03 +08:00
|
|
|
|
|
|
|
// Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs
|
|
|
|
// is specified, or -std is set to a conforming mode.
|
|
|
|
// Trigraphs are disabled by default in c++1z onwards.
|
|
|
|
Opts.Trigraphs = !Opts.GNUMode && !Opts.MSVCCompat && !Opts.CPlusPlus1z;
|
2014-12-24 06:32:37 +08:00
|
|
|
Opts.Trigraphs =
|
|
|
|
Args.hasFlag(OPT_ftrigraphs, OPT_fno_trigraphs, Opts.Trigraphs);
|
2009-12-01 11:16:53 +08:00
|
|
|
|
2009-12-17 04:10:18 +08:00
|
|
|
Opts.DollarIdents = Args.hasFlag(OPT_fdollars_in_identifiers,
|
|
|
|
OPT_fno_dollars_in_identifiers,
|
2010-12-04 09:50:27 +08:00
|
|
|
Opts.DollarIdents);
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.PascalStrings = Args.hasArg(OPT_fpascal_strings);
|
2014-02-13 07:50:26 +08:00
|
|
|
Opts.VtorDispMode = getLastArgIntValue(Args, OPT_vtordisp_mode_EQ, 1, Diags);
|
2010-09-03 07:59:25 +08:00
|
|
|
Opts.Borland = Args.hasArg(OPT_fborland_extensions);
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings);
|
2011-04-23 14:30:43 +08:00
|
|
|
Opts.ConstStrings = Args.hasFlag(OPT_fconst_strings, OPT_fno_const_strings,
|
|
|
|
Opts.ConstStrings);
|
2009-12-01 11:16:53 +08:00
|
|
|
if (Args.hasArg(OPT_fno_lax_vector_conversions))
|
2010-02-07 07:23:06 +08:00
|
|
|
Opts.LaxVectorConversions = 0;
|
|
|
|
if (Args.hasArg(OPT_fno_threadsafe_statics))
|
2010-02-11 16:02:13 +08:00
|
|
|
Opts.ThreadsafeStatics = 0;
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.Exceptions = Args.hasArg(OPT_fexceptions);
|
2011-02-22 09:52:06 +08:00
|
|
|
Opts.ObjCExceptions = Args.hasArg(OPT_fobjc_exceptions);
|
2011-02-23 11:16:42 +08:00
|
|
|
Opts.CXXExceptions = Args.hasArg(OPT_fcxx_exceptions);
|
|
|
|
Opts.SjLjExceptions = Args.hasArg(OPT_fsjlj_exceptions);
|
2016-02-20 17:23:47 +08:00
|
|
|
Opts.ExternCNoUnwind = Args.hasArg(OPT_fexternc_nounwind);
|
2011-03-19 05:23:38 +08:00
|
|
|
Opts.TraditionalCPP = Args.hasArg(OPT_traditional_cpp);
|
2011-02-23 11:16:42 +08:00
|
|
|
|
2016-01-27 04:15:02 +08:00
|
|
|
Opts.RTTI = Opts.CPlusPlus && !Args.hasArg(OPT_fno_rtti);
|
2014-07-02 06:24:56 +08:00
|
|
|
Opts.RTTIData = Opts.RTTI && !Args.hasArg(OPT_fno_rtti_data);
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.Blocks = Args.hasArg(OPT_fblocks);
|
2011-09-10 04:41:01 +08:00
|
|
|
Opts.BlocksRuntimeOptional = Args.hasArg(OPT_fblocks_runtime_optional);
|
2015-10-22 11:52:15 +08:00
|
|
|
Opts.Coroutines = Args.hasArg(OPT_fcoroutines);
|
2012-01-04 01:07:34 +08:00
|
|
|
Opts.Modules = Args.hasArg(OPT_fmodules);
|
2014-04-11 19:47:45 +08:00
|
|
|
Opts.ModulesStrictDeclUse = Args.hasArg(OPT_fmodules_strict_decluse);
|
|
|
|
Opts.ModulesDeclUse =
|
|
|
|
Args.hasArg(OPT_fmodules_decluse) || Opts.ModulesStrictDeclUse;
|
2015-05-02 05:22:17 +08:00
|
|
|
Opts.ModulesLocalVisibility =
|
|
|
|
Args.hasArg(OPT_fmodules_local_submodule_visibility);
|
2014-04-23 20:57:01 +08:00
|
|
|
Opts.ModulesSearchAll = Opts.Modules &&
|
|
|
|
!Args.hasArg(OPT_fno_modules_search_all) &&
|
|
|
|
Args.hasArg(OPT_fmodules_search_all);
|
2014-05-07 10:25:43 +08:00
|
|
|
Opts.ModulesErrorRecovery = !Args.hasArg(OPT_fno_modules_error_recovery);
|
2015-02-20 19:44:41 +08:00
|
|
|
Opts.ImplicitModules = !Args.hasArg(OPT_fno_implicit_modules);
|
2013-09-09 17:17:24 +08:00
|
|
|
Opts.CharIsSigned = Opts.OpenCL || !Args.hasArg(OPT_fno_signed_char);
|
2012-09-06 01:30:57 +08:00
|
|
|
Opts.WChar = Opts.CPlusPlus && !Args.hasArg(OPT_fno_wchar);
|
2014-02-25 02:43:28 +08:00
|
|
|
Opts.ShortWChar = Args.hasFlag(OPT_fshort_wchar, OPT_fno_short_wchar, false);
|
2010-10-08 08:25:19 +08:00
|
|
|
Opts.ShortEnums = Args.hasArg(OPT_fshort_enums);
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.Freestanding = Args.hasArg(OPT_ffreestanding);
|
|
|
|
Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
|
2016-01-06 22:35:46 +08:00
|
|
|
if (!Opts.NoBuiltin)
|
|
|
|
getAllNoBuiltinFuncValues(Args, Opts.NoBuiltinFuncs);
|
2013-07-23 08:13:01 +08:00
|
|
|
Opts.NoMathBuiltin = Args.hasArg(OPT_fno_math_builtin);
|
2015-03-20 08:31:07 +08:00
|
|
|
Opts.SizedDeallocation = Args.hasArg(OPT_fsized_deallocation);
|
2015-05-22 09:11:10 +08:00
|
|
|
Opts.ConceptsTS = Args.hasArg(OPT_fconcepts_ts);
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions);
|
2010-04-10 03:03:51 +08:00
|
|
|
Opts.AccessControl = !Args.hasArg(OPT_fno_access_control);
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors);
|
2013-09-09 17:17:24 +08:00
|
|
|
Opts.MathErrno = !Opts.OpenCL && Args.hasArg(OPT_fmath_errno);
|
2013-06-15 01:17:23 +08:00
|
|
|
Opts.InstantiationDepth =
|
|
|
|
getLastArgIntValue(Args, OPT_ftemplate_depth, 256, Diags);
|
2013-11-07 03:31:51 +08:00
|
|
|
Opts.ArrowDepth =
|
|
|
|
getLastArgIntValue(Args, OPT_foperator_arrow_depth, 256, Diags);
|
2013-06-15 01:17:23 +08:00
|
|
|
Opts.ConstexprCallDepth =
|
|
|
|
getLastArgIntValue(Args, OPT_fconstexpr_depth, 512, Diags);
|
|
|
|
Opts.ConstexprStepLimit =
|
|
|
|
getLastArgIntValue(Args, OPT_fconstexpr_steps, 1048576, Diags);
|
|
|
|
Opts.BracketDepth = getLastArgIntValue(Args, OPT_fbracket_depth, 256, Diags);
|
2011-04-23 06:18:13 +08:00
|
|
|
Opts.DelayedTemplateParsing = Args.hasArg(OPT_fdelayed_template_parsing);
|
2013-06-15 01:17:23 +08:00
|
|
|
Opts.NumLargeByValueCopy =
|
|
|
|
getLastArgIntValue(Args, OPT_Wlarge_by_value_copy_EQ, 0, Diags);
|
2011-02-01 23:15:22 +08:00
|
|
|
Opts.MSBitfields = Args.hasArg(OPT_mms_bitfields);
|
2010-05-21 00:54:55 +08:00
|
|
|
Opts.ObjCConstantStringClass =
|
|
|
|
Args.getLastArgValue(OPT_fconstant_string_class);
|
2010-12-24 05:35:43 +08:00
|
|
|
Opts.ObjCDefaultSynthProperties =
|
2013-09-28 04:21:48 +08:00
|
|
|
!Args.hasArg(OPT_disable_objc_default_synthesize_properties);
|
2012-11-16 03:02:45 +08:00
|
|
|
Opts.EncodeExtendedBlockSig =
|
|
|
|
Args.hasArg(OPT_fencode_extended_block_signature);
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
|
2013-06-15 01:17:23 +08:00
|
|
|
Opts.PackStruct = getLastArgIntValue(Args, OPT_fpack_struct_EQ, 0, Diags);
|
2014-08-06 02:37:48 +08:00
|
|
|
Opts.MaxTypeAlign = getLastArgIntValue(Args, OPT_fmax_type_align_EQ, 0, Diags);
|
2016-05-04 10:58:24 +08:00
|
|
|
Opts.AlignDouble = Args.hasArg(OPT_malign_double);
|
2013-06-15 01:17:23 +08:00
|
|
|
Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
|
|
|
|
Opts.PIELevel = getLastArgIntValue(Args, OPT_pie_level, 0, Diags);
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.Static = Args.hasArg(OPT_static_define);
|
Extend the ExternalASTSource interface to allow the AST source to
provide the layout of records, rather than letting Clang compute
the layout itself. LLDB provides the motivation for this feature:
because various layout-altering attributes (packed, aligned, etc.)
don't get reliably get placed into DWARF, the record layouts computed
by LLDB from the reconstructed records differ from the actual layouts,
and badness occurs. This interface lets the DWARF data drive layout,
so we don't need the attributes preserved to get the answer write.
The testing methodology for this change is fun. I've introduced a
variant of -fdump-record-layouts called -fdump-record-layouts-simple
that always has the simple C format and provides size/alignment/field
offsets. There is also a -cc1 option -foverride-record-layout=<file>
to take the output of -fdump-record-layouts-simple and parse it to
produce a set of overridden layouts, which is introduced into the AST
via a testing-only ExternalASTSource (called
LayoutOverrideSource). Each test contains a number of records to lay
out, which use various layout-changing attributes, and then dumps the
layouts. We then run the test again, using the preprocessor to
eliminate the layout-changing attributes entirely (which would give us
different layouts for the records), but supplying the
previously-computed record layouts. Finally, we diff the layouts
produced from the two runs to be sure that they are identical.
Note that this code makes the assumption that we don't *have* to
provide the offsets of bases or virtual bases to get the layout right,
because the alignment attributes don't affect it. I believe this
assumption holds, but if it does not, we can extend
LayoutOverrideSource to also provide base offset information.
Fixes the Clang side of <rdar://problem/10169539>.
llvm-svn: 149055
2012-01-26 15:55:45 +08:00
|
|
|
Opts.DumpRecordLayoutsSimple = Args.hasArg(OPT_fdump_record_layouts_simple);
|
2015-08-05 23:08:53 +08:00
|
|
|
Opts.DumpRecordLayouts = Opts.DumpRecordLayoutsSimple
|
Extend the ExternalASTSource interface to allow the AST source to
provide the layout of records, rather than letting Clang compute
the layout itself. LLDB provides the motivation for this feature:
because various layout-altering attributes (packed, aligned, etc.)
don't get reliably get placed into DWARF, the record layouts computed
by LLDB from the reconstructed records differ from the actual layouts,
and badness occurs. This interface lets the DWARF data drive layout,
so we don't need the attributes preserved to get the answer write.
The testing methodology for this change is fun. I've introduced a
variant of -fdump-record-layouts called -fdump-record-layouts-simple
that always has the simple C format and provides size/alignment/field
offsets. There is also a -cc1 option -foverride-record-layout=<file>
to take the output of -fdump-record-layouts-simple and parse it to
produce a set of overridden layouts, which is introduced into the AST
via a testing-only ExternalASTSource (called
LayoutOverrideSource). Each test contains a number of records to lay
out, which use various layout-changing attributes, and then dumps the
layouts. We then run the test again, using the preprocessor to
eliminate the layout-changing attributes entirely (which would give us
different layouts for the records), but supplying the
previously-computed record layouts. Finally, we diff the layouts
produced from the two runs to be sure that they are identical.
Note that this code makes the assumption that we don't *have* to
provide the offsets of bases or virtual bases to get the layout right,
because the alignment attributes don't affect it. I believe this
assumption holds, but if it does not, we can extend
LayoutOverrideSource to also provide base offset information.
Fixes the Clang side of <rdar://problem/10169539>.
llvm-svn: 149055
2012-01-26 15:55:45 +08:00
|
|
|
|| Args.hasArg(OPT_fdump_record_layouts);
|
2010-04-18 04:15:18 +08:00
|
|
|
Opts.DumpVTableLayouts = Args.hasArg(OPT_fdump_vtable_layouts);
|
2010-07-10 01:35:33 +08:00
|
|
|
Opts.SpellChecking = !Args.hasArg(OPT_fno_spell_checking);
|
2010-04-15 23:06:22 +08:00
|
|
|
Opts.NoBitFieldTypeAlign = Args.hasArg(OPT_fno_bitfield_type_align);
|
2010-12-04 09:50:56 +08:00
|
|
|
Opts.SinglePrecisionConstants = Args.hasArg(OPT_cl_single_precision_constant);
|
2010-12-04 09:51:23 +08:00
|
|
|
Opts.FastRelaxedMath = Args.hasArg(OPT_cl_fast_relaxed_math);
|
2011-12-13 05:14:55 +08:00
|
|
|
Opts.HexagonQdsp6Compat = Args.hasArg(OPT_mqdsp6_compat);
|
2011-03-19 06:38:29 +08:00
|
|
|
Opts.FakeAddressSpaceMap = Args.hasArg(OPT_ffake_address_space_map);
|
2011-04-10 06:50:59 +08:00
|
|
|
Opts.ParseUnknownAnytype = Args.hasArg(OPT_funknown_anytype);
|
2011-07-14 01:56:40 +08:00
|
|
|
Opts.DebuggerSupport = Args.hasArg(OPT_fdebugger_support);
|
2012-02-04 09:29:37 +08:00
|
|
|
Opts.DebuggerCastResultToId = Args.hasArg(OPT_fdebugger_cast_result_to_id);
|
2012-03-07 04:06:33 +08:00
|
|
|
Opts.DebuggerObjCLiteral = Args.hasArg(OPT_fdebugger_objc_literal);
|
2011-11-02 09:53:16 +08:00
|
|
|
Opts.ApplePragmaPack = Args.hasArg(OPT_fapple_pragma_pack);
|
2016-02-20 06:25:36 +08:00
|
|
|
Opts.CurrentModule = Args.getLastArgValue(OPT_fmodule_name_EQ);
|
2015-03-03 03:01:14 +08:00
|
|
|
Opts.AppExt = Args.hasArg(OPT_fapplication_extension);
|
2015-02-03 05:56:15 +08:00
|
|
|
Opts.ModuleFeatures = Args.getAllArgValues(OPT_fmodule_feature);
|
2015-06-24 02:20:18 +08:00
|
|
|
std::sort(Opts.ModuleFeatures.begin(), Opts.ModuleFeatures.end());
|
2015-05-15 07:44:18 +08:00
|
|
|
Opts.NativeHalfType |= Args.hasArg(OPT_fnative_half_type);
|
2016-03-19 00:58:36 +08:00
|
|
|
Opts.NativeHalfArgsAndReturns |= Args.hasArg(OPT_fnative_half_arguments_and_returns);
|
|
|
|
// Enable HalfArgsAndReturns if present in Args or if NativeHalfArgsAndReturns
|
|
|
|
// is enabled.
|
|
|
|
Opts.HalfArgsAndReturns = Args.hasArg(OPT_fallow_half_arguments_and_returns)
|
|
|
|
| Opts.NativeHalfArgsAndReturns;
|
2015-01-17 07:05:28 +08:00
|
|
|
Opts.GNUAsm = !Args.hasArg(OPT_fno_gnu_inline_asm);
|
2014-07-23 23:30:23 +08:00
|
|
|
|
2015-10-05 01:51:05 +08:00
|
|
|
// __declspec is enabled by default for the PS4 by the driver, and also
|
|
|
|
// enabled for Microsoft Extensions or Borland Extensions, here.
|
|
|
|
//
|
|
|
|
// FIXME: __declspec is also currently enabled for CUDA, but isn't really a
|
|
|
|
// CUDA extension, however it is required for supporting cuda_builtin_vars.h,
|
|
|
|
// which uses __declspec(property). Once that has been rewritten in terms of
|
|
|
|
// something more generic, remove the Opts.CUDA term here.
|
|
|
|
Opts.DeclSpecKeyword =
|
|
|
|
Args.hasFlag(OPT_fdeclspec, OPT_fno_declspec,
|
|
|
|
(Opts.MicrosoftExt || Opts.Borland || Opts.CUDA));
|
|
|
|
|
2015-05-16 04:05:43 +08:00
|
|
|
// For now, we only support local submodule visibility in C++ (because we
|
|
|
|
// heavily depend on the ODR for merging redefinitions).
|
|
|
|
if (Opts.ModulesLocalVisibility && !Opts.CPlusPlus)
|
|
|
|
Diags.Report(diag::err_drv_argument_not_allowed_with)
|
|
|
|
<< "-fmodules-local-submodule-visibility" << "C";
|
|
|
|
|
2013-09-13 20:04:22 +08:00
|
|
|
if (Arg *A = Args.getLastArg(OPT_faddress_space_map_mangling_EQ)) {
|
|
|
|
switch (llvm::StringSwitch<unsigned>(A->getValue())
|
|
|
|
.Case("target", LangOptions::ASMM_Target)
|
|
|
|
.Case("no", LangOptions::ASMM_Off)
|
|
|
|
.Case("yes", LangOptions::ASMM_On)
|
|
|
|
.Default(255)) {
|
|
|
|
default:
|
2015-08-05 23:08:53 +08:00
|
|
|
Diags.Report(diag::err_drv_invalid_value)
|
2013-09-13 20:04:22 +08:00
|
|
|
<< "-faddress-space-map-mangling=" << A->getValue();
|
|
|
|
break;
|
|
|
|
case LangOptions::ASMM_Target:
|
|
|
|
Opts.setAddressSpaceMapMangling(LangOptions::ASMM_Target);
|
|
|
|
break;
|
|
|
|
case LangOptions::ASMM_On:
|
|
|
|
Opts.setAddressSpaceMapMangling(LangOptions::ASMM_On);
|
|
|
|
break;
|
|
|
|
case LangOptions::ASMM_Off:
|
|
|
|
Opts.setAddressSpaceMapMangling(LangOptions::ASMM_Off);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-12 05:05:00 +08:00
|
|
|
if (Arg *A = Args.getLastArg(OPT_fms_memptr_rep_EQ)) {
|
|
|
|
LangOptions::PragmaMSPointersToMembersKind InheritanceModel =
|
|
|
|
llvm::StringSwitch<LangOptions::PragmaMSPointersToMembersKind>(
|
|
|
|
A->getValue())
|
|
|
|
.Case("single",
|
|
|
|
LangOptions::PPTMK_FullGeneralitySingleInheritance)
|
|
|
|
.Case("multiple",
|
|
|
|
LangOptions::PPTMK_FullGeneralityMultipleInheritance)
|
|
|
|
.Case("virtual",
|
|
|
|
LangOptions::PPTMK_FullGeneralityVirtualInheritance)
|
|
|
|
.Default(LangOptions::PPTMK_BestCase);
|
|
|
|
if (InheritanceModel == LangOptions::PPTMK_BestCase)
|
|
|
|
Diags.Report(diag::err_drv_invalid_value)
|
|
|
|
<< "-fms-memptr-rep=" << A->getValue();
|
|
|
|
|
|
|
|
Opts.setMSPointerToMemberRepresentationMethod(InheritanceModel);
|
|
|
|
}
|
|
|
|
|
2016-05-18 17:06:38 +08:00
|
|
|
// Check for MS default calling conventions being specified.
|
|
|
|
if (Arg *A = Args.getLastArg(OPT_fdefault_calling_conv_EQ)) {
|
|
|
|
LangOptions::DefaultCallingConvention DefaultCC =
|
|
|
|
llvm::StringSwitch<LangOptions::DefaultCallingConvention>(
|
|
|
|
A->getValue())
|
|
|
|
.Case("cdecl", LangOptions::DCC_CDecl)
|
|
|
|
.Case("fastcall", LangOptions::DCC_FastCall)
|
|
|
|
.Case("stdcall", LangOptions::DCC_StdCall)
|
|
|
|
.Case("vectorcall", LangOptions::DCC_VectorCall)
|
|
|
|
.Default(LangOptions::DCC_None);
|
|
|
|
if (DefaultCC == LangOptions::DCC_None)
|
|
|
|
Diags.Report(diag::err_drv_invalid_value)
|
|
|
|
<< "-fdefault-calling-conv=" << A->getValue();
|
|
|
|
|
|
|
|
llvm::Triple T(TargetOpts.Triple);
|
|
|
|
llvm::Triple::ArchType Arch = T.getArch();
|
|
|
|
bool emitError = (DefaultCC == LangOptions::DCC_FastCall ||
|
|
|
|
DefaultCC == LangOptions::DCC_StdCall) &&
|
|
|
|
Arch != llvm::Triple::x86;
|
|
|
|
emitError |= DefaultCC == LangOptions::DCC_VectorCall &&
|
|
|
|
!(Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64);
|
|
|
|
if (emitError)
|
|
|
|
Diags.Report(diag::err_drv_argument_not_allowed_with)
|
|
|
|
<< A->getSpelling() << T.getTriple();
|
|
|
|
else
|
|
|
|
Opts.setDefaultCallingConv(DefaultCC);
|
|
|
|
}
|
|
|
|
|
|
|
|
// -mrtd option
|
|
|
|
if (Arg *A = Args.getLastArg(OPT_mrtd)) {
|
|
|
|
if (Opts.getDefaultCallingConv() != LangOptions::DCC_None)
|
|
|
|
Diags.Report(diag::err_drv_argument_not_allowed_with)
|
|
|
|
<< A->getSpelling() << "-fdefault-calling-conv";
|
|
|
|
else {
|
|
|
|
llvm::Triple T(TargetOpts.Triple);
|
|
|
|
if (T.getArch() != llvm::Triple::x86)
|
|
|
|
Diags.Report(diag::err_drv_argument_not_allowed_with)
|
|
|
|
<< A->getSpelling() << T.getTriple();
|
|
|
|
else
|
|
|
|
Opts.setDefaultCallingConv(LangOptions::DCC_StdCall);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-20 12:24:19 +08:00
|
|
|
// Check if -fopenmp is specified.
|
2016-05-27 12:13:39 +08:00
|
|
|
Opts.OpenMP = Args.hasArg(options::OPT_fopenmp) ? 1 : 0;
|
2015-07-14 06:54:53 +08:00
|
|
|
Opts.OpenMPUseTLS =
|
|
|
|
Opts.OpenMP && !Args.hasArg(options::OPT_fnoopenmp_use_tls);
|
2016-01-06 21:42:12 +08:00
|
|
|
Opts.OpenMPIsDevice =
|
|
|
|
Opts.OpenMP && Args.hasArg(options::OPT_fopenmp_is_device);
|
|
|
|
|
2016-05-26 19:10:11 +08:00
|
|
|
if (Opts.OpenMP) {
|
2016-05-27 12:13:39 +08:00
|
|
|
int Version =
|
|
|
|
getLastArgIntValue(Args, OPT_fopenmp_version_EQ, Opts.OpenMP, Diags);
|
|
|
|
if (Version != 0)
|
2016-05-26 19:10:11 +08:00
|
|
|
Opts.OpenMP = Version;
|
|
|
|
// Provide diagnostic when a given target is not expected to be an OpenMP
|
|
|
|
// device or host.
|
|
|
|
if (!Opts.OpenMPIsDevice) {
|
|
|
|
switch (T.getArch()) {
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
// Add unsupported host targets here:
|
|
|
|
case llvm::Triple::nvptx:
|
|
|
|
case llvm::Triple::nvptx64:
|
|
|
|
Diags.Report(clang::diag::err_drv_omp_host_target_not_supported)
|
|
|
|
<< TargetOpts.Triple;
|
|
|
|
break;
|
|
|
|
}
|
2016-02-08 23:59:20 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-06 21:42:12 +08:00
|
|
|
// Get the OpenMP target triples if any.
|
2016-03-14 23:57:41 +08:00
|
|
|
if (Arg *A = Args.getLastArg(options::OPT_fomptargets_EQ)) {
|
2016-01-06 21:42:12 +08:00
|
|
|
|
|
|
|
for (unsigned i = 0; i < A->getNumValues(); ++i) {
|
|
|
|
llvm::Triple TT(A->getValue(i));
|
|
|
|
|
|
|
|
if (TT.getArch() == llvm::Triple::UnknownArch)
|
|
|
|
Diags.Report(clang::diag::err_drv_invalid_omp_target) << A->getValue(i);
|
|
|
|
else
|
|
|
|
Opts.OMPTargetTriples.push_back(TT);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get OpenMP host file path if any and report if a non existent file is
|
|
|
|
// found
|
2016-03-14 23:57:41 +08:00
|
|
|
if (Arg *A = Args.getLastArg(options::OPT_fomp_host_ir_file_path)) {
|
2016-01-06 21:42:12 +08:00
|
|
|
Opts.OMPHostIRFile = A->getValue();
|
|
|
|
if (!llvm::sys::fs::exists(Opts.OMPHostIRFile))
|
|
|
|
Diags.Report(clang::diag::err_drv_omp_host_ir_file_not_found)
|
|
|
|
<< Opts.OMPHostIRFile;
|
|
|
|
}
|
2013-01-15 14:45:29 +08:00
|
|
|
|
2011-04-23 17:27:53 +08:00
|
|
|
// Record whether the __DEPRECATED define was requested.
|
|
|
|
Opts.Deprecated = Args.hasFlag(OPT_fdeprecated_macro,
|
|
|
|
OPT_fno_deprecated_macro,
|
|
|
|
Opts.Deprecated);
|
|
|
|
|
2009-12-01 11:16:53 +08:00
|
|
|
// FIXME: Eliminate this dependency.
|
2012-08-09 00:09:15 +08:00
|
|
|
unsigned Opt = getOptimizationLevel(Args, IK, Diags),
|
2013-04-11 05:30:03 +08:00
|
|
|
OptSize = getOptimizationLevelSize(Args);
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.Optimize = Opt != 0;
|
2012-08-09 00:09:15 +08:00
|
|
|
Opts.OptimizeSize = OptSize != 0;
|
2009-12-01 11:16:53 +08:00
|
|
|
|
|
|
|
// This is the __NO_INLINE__ define, which just depends on things like the
|
|
|
|
// optimization level and -fno-inline, not actually whether the backend has
|
|
|
|
// inlining enabled.
|
2012-03-16 06:31:42 +08:00
|
|
|
Opts.NoInlineDefine = !Opt || Args.hasArg(OPT_fno_inline);
|
2009-12-01 11:16:53 +08:00
|
|
|
|
2014-12-11 00:41:14 +08:00
|
|
|
Opts.FastMath = Args.hasArg(OPT_ffast_math) ||
|
|
|
|
Args.hasArg(OPT_cl_fast_relaxed_math);
|
|
|
|
Opts.FiniteMathOnly = Args.hasArg(OPT_ffinite_math_only) ||
|
|
|
|
Args.hasArg(OPT_cl_finite_math_only) ||
|
|
|
|
Args.hasArg(OPT_cl_fast_relaxed_math);
|
2015-10-02 22:56:37 +08:00
|
|
|
Opts.UnsafeFPMath = Args.hasArg(OPT_menable_unsafe_fp_math) ||
|
|
|
|
Args.hasArg(OPT_cl_unsafe_math_optimizations) ||
|
|
|
|
Args.hasArg(OPT_cl_fast_relaxed_math);
|
2012-01-02 22:19:45 +08:00
|
|
|
|
2012-09-13 14:41:18 +08:00
|
|
|
Opts.RetainCommentsFromSystemHeaders =
|
|
|
|
Args.hasArg(OPT_fretain_comments_from_system_headers);
|
|
|
|
|
2013-06-15 01:17:23 +08:00
|
|
|
unsigned SSP = getLastArgIntValue(Args, OPT_stack_protector, 0, Diags);
|
2009-12-01 11:16:53 +08:00
|
|
|
switch (SSP) {
|
|
|
|
default:
|
|
|
|
Diags.Report(diag::err_drv_invalid_value)
|
|
|
|
<< Args.getLastArg(OPT_stack_protector)->getAsString(Args) << SSP;
|
|
|
|
break;
|
2011-09-14 01:21:33 +08:00
|
|
|
case 0: Opts.setStackProtector(LangOptions::SSPOff); break;
|
|
|
|
case 1: Opts.setStackProtector(LangOptions::SSPOn); break;
|
2014-02-11 09:35:14 +08:00
|
|
|
case 2: Opts.setStackProtector(LangOptions::SSPStrong); break;
|
|
|
|
case 3: Opts.setStackProtector(LangOptions::SSPReq); break;
|
2009-12-01 11:16:53 +08:00
|
|
|
}
|
2012-11-06 06:04:41 +08:00
|
|
|
|
|
|
|
// Parse -fsanitize= arguments.
|
Reimplement -fsanitize-recover family of flags.
Introduce the following -fsanitize-recover flags:
- -fsanitize-recover=<list>: Enable recovery for selected checks or
group of checks. It is forbidden to explicitly list unrecoverable
sanitizers here (that is, "address", "unreachable", "return").
- -fno-sanitize-recover=<list>: Disable recovery for selected checks or
group of checks.
- -f(no-)?sanitize-recover is now a synonym for
-f(no-)?sanitize-recover=undefined,integer and will soon be deprecated.
These flags are parsed left to right, and mask of "recoverable"
sanitizer is updated accordingly, much like what we do for -fsanitize= flags.
-fsanitize= and -fsanitize-recover= flag families are independent.
CodeGen change: If there is a single UBSan handler function, responsible
for implementing multiple checks, which have different recoverable setting,
then we emit two handler calls instead of one:
the first one for the set of "unrecoverable" checks, another one - for
set of "recoverable" checks. If all checks implemented by a handler have the
same recoverability setting, then the generated code will be the same.
llvm-svn: 225719
2015-01-13 06:39:12 +08:00
|
|
|
parseSanitizerKinds("-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ),
|
|
|
|
Diags, Opts.Sanitize);
|
2014-10-10 01:53:04 +08:00
|
|
|
// -fsanitize-address-field-padding=N has to be a LangOpt, parse it here.
|
2014-11-11 09:26:14 +08:00
|
|
|
Opts.SanitizeAddressFieldPadding =
|
2014-10-10 01:53:04 +08:00
|
|
|
getLastArgIntValue(Args, OPT_fsanitize_address_field_padding, 0, Diags);
|
2015-02-05 01:40:08 +08:00
|
|
|
Opts.SanitizerBlacklistFiles = Args.getAllArgValues(OPT_fsanitize_blacklist);
|
2009-12-01 11:16:53 +08:00
|
|
|
}
|
|
|
|
|
2009-12-03 13:11:16 +08:00
|
|
|
static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
|
2010-11-04 06:45:23 +08:00
|
|
|
FileManager &FileMgr,
|
2011-09-26 07:23:43 +08:00
|
|
|
DiagnosticsEngine &Diags) {
|
2012-05-01 22:57:16 +08:00
|
|
|
using namespace options;
|
2010-05-21 00:54:55 +08:00
|
|
|
Opts.ImplicitPCHInclude = Args.getLastArgValue(OPT_include_pch);
|
|
|
|
Opts.ImplicitPTHInclude = Args.getLastArgValue(OPT_include_pth);
|
2009-12-01 11:16:53 +08:00
|
|
|
if (const Arg *A = Args.getLastArg(OPT_token_cache))
|
2012-11-01 12:30:05 +08:00
|
|
|
Opts.TokenCache = A->getValue();
|
2009-12-01 11:16:53 +08:00
|
|
|
else
|
|
|
|
Opts.TokenCache = Opts.ImplicitPTHInclude;
|
|
|
|
Opts.UsePredefines = !Args.hasArg(OPT_undef);
|
2010-03-20 00:15:56 +08:00
|
|
|
Opts.DetailedRecord = Args.hasArg(OPT_detailed_preprocessing_record);
|
2010-07-27 08:27:13 +08:00
|
|
|
Opts.DisablePCHValidation = Args.hasArg(OPT_fno_validate_pch);
|
2010-10-15 04:14:25 +08:00
|
|
|
|
2010-10-15 04:14:18 +08:00
|
|
|
Opts.DumpDeserializedPCHDecls = Args.hasArg(OPT_dump_deserialized_pch_decls);
|
2015-06-09 09:57:17 +08:00
|
|
|
for (const Arg *A : Args.filtered(OPT_error_on_deserialized_pch_decl))
|
2012-11-01 12:30:05 +08:00
|
|
|
Opts.DeserializedPCHDeclsToErrorOn.insert(A->getValue());
|
2010-07-27 08:27:13 +08:00
|
|
|
|
Introduce basic support for loading a precompiled preamble while
reparsing an ASTUnit. When saving a preamble, create a buffer larger
than the actual file we're working with but fill everything from the
end of the preamble to the end of the file with spaces (so the lexer
will quickly skip them). When we load the file, create a buffer of the
same size, filling it with the file and then spaces. Then, instruct
the lexer to start lexing after the preamble, therefore continuing the
parse from the spot where the preamble left off.
It's now possible to perform a simple preamble build + parse (+
reparse) with ASTUnit. However, one has to disable a bunch of checking
in the PCH reader to do so. That part isn't committed; it will likely
be handled with some other kind of flag (e.g., -fno-validate-pch).
As part of this, fix some issues with null termination of the memory
buffers created for the preamble; we were trying to explicitly
NULL-terminate them, even though they were also getting implicitly
NULL terminated, leading to excess warnings about NULL characters in
source files.
llvm-svn: 109445
2010-07-27 05:36:20 +08:00
|
|
|
if (const Arg *A = Args.getLastArg(OPT_preamble_bytes_EQ)) {
|
2012-11-01 12:30:05 +08:00
|
|
|
StringRef Value(A->getValue());
|
Introduce basic support for loading a precompiled preamble while
reparsing an ASTUnit. When saving a preamble, create a buffer larger
than the actual file we're working with but fill everything from the
end of the preamble to the end of the file with spaces (so the lexer
will quickly skip them). When we load the file, create a buffer of the
same size, filling it with the file and then spaces. Then, instruct
the lexer to start lexing after the preamble, therefore continuing the
parse from the spot where the preamble left off.
It's now possible to perform a simple preamble build + parse (+
reparse) with ASTUnit. However, one has to disable a bunch of checking
in the PCH reader to do so. That part isn't committed; it will likely
be handled with some other kind of flag (e.g., -fno-validate-pch).
As part of this, fix some issues with null termination of the memory
buffers created for the preamble; we were trying to explicitly
NULL-terminate them, even though they were also getting implicitly
NULL terminated, leading to excess warnings about NULL characters in
source files.
llvm-svn: 109445
2010-07-27 05:36:20 +08:00
|
|
|
size_t Comma = Value.find(',');
|
|
|
|
unsigned Bytes = 0;
|
|
|
|
unsigned EndOfLine = 0;
|
2010-10-21 11:16:25 +08:00
|
|
|
|
2011-07-23 18:55:15 +08:00
|
|
|
if (Comma == StringRef::npos ||
|
Introduce basic support for loading a precompiled preamble while
reparsing an ASTUnit. When saving a preamble, create a buffer larger
than the actual file we're working with but fill everything from the
end of the preamble to the end of the file with spaces (so the lexer
will quickly skip them). When we load the file, create a buffer of the
same size, filling it with the file and then spaces. Then, instruct
the lexer to start lexing after the preamble, therefore continuing the
parse from the spot where the preamble left off.
It's now possible to perform a simple preamble build + parse (+
reparse) with ASTUnit. However, one has to disable a bunch of checking
in the PCH reader to do so. That part isn't committed; it will likely
be handled with some other kind of flag (e.g., -fno-validate-pch).
As part of this, fix some issues with null termination of the memory
buffers created for the preamble; we were trying to explicitly
NULL-terminate them, even though they were also getting implicitly
NULL terminated, leading to excess warnings about NULL characters in
source files.
llvm-svn: 109445
2010-07-27 05:36:20 +08:00
|
|
|
Value.substr(0, Comma).getAsInteger(10, Bytes) ||
|
|
|
|
Value.substr(Comma + 1).getAsInteger(10, EndOfLine))
|
|
|
|
Diags.Report(diag::err_drv_preamble_format);
|
|
|
|
else {
|
|
|
|
Opts.PrecompiledPreambleBytes.first = Bytes;
|
|
|
|
Opts.PrecompiledPreambleBytes.second = (EndOfLine != 0);
|
|
|
|
}
|
|
|
|
}
|
2010-10-21 11:16:25 +08:00
|
|
|
|
2009-12-01 11:16:53 +08:00
|
|
|
// Add macros from the command line.
|
2015-06-09 09:57:17 +08:00
|
|
|
for (const Arg *A : Args.filtered(OPT_D, OPT_U)) {
|
|
|
|
if (A->getOption().matches(OPT_D))
|
|
|
|
Opts.addMacroDef(A->getValue());
|
2009-12-01 11:16:53 +08:00
|
|
|
else
|
2015-06-09 09:57:17 +08:00
|
|
|
Opts.addMacroUndef(A->getValue());
|
2009-12-01 11:16:53 +08:00
|
|
|
}
|
|
|
|
|
2010-05-21 00:54:55 +08:00
|
|
|
Opts.MacroIncludes = Args.getAllArgValues(OPT_imacros);
|
2009-12-01 11:16:53 +08:00
|
|
|
|
|
|
|
// Add the ordered list of -includes.
|
2015-06-09 09:57:17 +08:00
|
|
|
for (const Arg *A : Args.filtered(OPT_include))
|
2015-05-30 03:42:19 +08:00
|
|
|
Opts.Includes.emplace_back(A->getValue());
|
2009-12-03 13:11:16 +08:00
|
|
|
|
2015-06-09 09:57:17 +08:00
|
|
|
for (const Arg *A : Args.filtered(OPT_chain_include))
|
2015-05-30 03:42:19 +08:00
|
|
|
Opts.ChainedIncludes.emplace_back(A->getValue());
|
2011-03-10 01:21:42 +08:00
|
|
|
|
2015-06-09 09:57:17 +08:00
|
|
|
for (const Arg *A : Args.filtered(OPT_remap_file)) {
|
|
|
|
std::pair<StringRef, StringRef> Split = StringRef(A->getValue()).split(';');
|
2009-12-03 13:11:16 +08:00
|
|
|
|
|
|
|
if (Split.second.empty()) {
|
2010-06-12 06:00:13 +08:00
|
|
|
Diags.Report(diag::err_drv_invalid_remap_file) << A->getAsString(Args);
|
2009-12-03 13:11:16 +08:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
Opts.addRemappedFile(Split.first, Split.second);
|
|
|
|
}
|
2015-06-09 09:57:17 +08:00
|
|
|
|
2011-06-16 07:02:42 +08:00
|
|
|
if (Arg *A = Args.getLastArg(OPT_fobjc_arc_cxxlib_EQ)) {
|
2012-11-01 12:30:05 +08:00
|
|
|
StringRef Name = A->getValue();
|
2011-06-16 07:02:42 +08:00
|
|
|
unsigned Library = llvm::StringSwitch<unsigned>(Name)
|
|
|
|
.Case("libc++", ARCXX_libcxx)
|
|
|
|
.Case("libstdc++", ARCXX_libstdcxx)
|
|
|
|
.Case("none", ARCXX_nolib)
|
|
|
|
.Default(~0U);
|
|
|
|
if (Library == ~0U)
|
|
|
|
Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name;
|
|
|
|
else
|
|
|
|
Opts.ObjCXXARCStandardLibrary = (ObjCXXARCStandardLibraryKind)Library;
|
|
|
|
}
|
2009-12-01 11:16:53 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void ParsePreprocessorOutputArgs(PreprocessorOutputOptions &Opts,
|
2013-01-30 09:52:57 +08:00
|
|
|
ArgList &Args,
|
|
|
|
frontend::ActionKind Action) {
|
2012-05-01 22:57:16 +08:00
|
|
|
using namespace options;
|
2013-01-30 09:52:57 +08:00
|
|
|
|
|
|
|
switch (Action) {
|
|
|
|
case frontend::ASTDeclList:
|
|
|
|
case frontend::ASTDump:
|
|
|
|
case frontend::ASTPrint:
|
|
|
|
case frontend::ASTView:
|
|
|
|
case frontend::EmitAssembly:
|
|
|
|
case frontend::EmitBC:
|
|
|
|
case frontend::EmitHTML:
|
|
|
|
case frontend::EmitLLVM:
|
|
|
|
case frontend::EmitLLVMOnly:
|
|
|
|
case frontend::EmitCodeGenOnly:
|
|
|
|
case frontend::EmitObj:
|
|
|
|
case frontend::FixIt:
|
|
|
|
case frontend::GenerateModule:
|
|
|
|
case frontend::GeneratePCH:
|
|
|
|
case frontend::GeneratePTH:
|
|
|
|
case frontend::ParseSyntaxOnly:
|
2013-03-28 00:47:18 +08:00
|
|
|
case frontend::ModuleFileInfo:
|
2014-02-06 06:21:15 +08:00
|
|
|
case frontend::VerifyPCH:
|
2013-01-30 09:52:57 +08:00
|
|
|
case frontend::PluginAction:
|
|
|
|
case frontend::PrintDeclContext:
|
|
|
|
case frontend::RewriteObjC:
|
|
|
|
case frontend::RewriteTest:
|
|
|
|
case frontend::RunAnalysis:
|
|
|
|
case frontend::MigrateSource:
|
|
|
|
Opts.ShowCPP = 0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case frontend::DumpRawTokens:
|
|
|
|
case frontend::DumpTokens:
|
|
|
|
case frontend::InitOnly:
|
|
|
|
case frontend::PrintPreamble:
|
|
|
|
case frontend::PrintPreprocessedInput:
|
|
|
|
case frontend::RewriteMacros:
|
|
|
|
case frontend::RunPreprocessorOnly:
|
|
|
|
Opts.ShowCPP = !Args.hasArg(OPT_dM);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.ShowComments = Args.hasArg(OPT_C);
|
2010-08-25 06:44:13 +08:00
|
|
|
Opts.ShowLineMarkers = !Args.hasArg(OPT_P);
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.ShowMacroComments = Args.hasArg(OPT_CC);
|
2010-08-25 06:44:13 +08:00
|
|
|
Opts.ShowMacros = Args.hasArg(OPT_dM) || Args.hasArg(OPT_dD);
|
2012-06-15 01:36:09 +08:00
|
|
|
Opts.RewriteIncludes = Args.hasArg(OPT_frewrite_includes);
|
2015-02-26 08:17:25 +08:00
|
|
|
Opts.UseLineDirectives = Args.hasArg(OPT_fuse_line_directives);
|
2009-12-01 11:16:53 +08:00
|
|
|
}
|
|
|
|
|
2016-04-09 00:52:05 +08:00
|
|
|
static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args,
|
|
|
|
DiagnosticsEngine &Diags) {
|
2012-05-01 22:57:16 +08:00
|
|
|
using namespace options;
|
2010-05-21 00:54:55 +08:00
|
|
|
Opts.ABI = Args.getLastArgValue(OPT_target_abi);
|
2016-04-09 00:52:05 +08:00
|
|
|
if (Arg *A = Args.getLastArg(OPT_meabi)) {
|
|
|
|
StringRef Value = A->getValue();
|
|
|
|
llvm::EABI EABIVersion = llvm::StringSwitch<llvm::EABI>(Value)
|
|
|
|
.Case("default", llvm::EABI::Default)
|
|
|
|
.Case("4", llvm::EABI::EABI4)
|
|
|
|
.Case("5", llvm::EABI::EABI5)
|
|
|
|
.Case("gnu", llvm::EABI::GNU)
|
|
|
|
.Default(llvm::EABI::Unknown);
|
|
|
|
if (EABIVersion == llvm::EABI::Unknown)
|
|
|
|
Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
|
|
|
|
<< Value;
|
|
|
|
else
|
|
|
|
Opts.EABIVersion = Value;
|
|
|
|
}
|
2010-05-21 00:54:55 +08:00
|
|
|
Opts.CPU = Args.getLastArgValue(OPT_target_cpu);
|
2013-08-22 05:59:03 +08:00
|
|
|
Opts.FPMath = Args.getLastArgValue(OPT_mfpmath);
|
2012-10-17 07:40:58 +08:00
|
|
|
Opts.FeaturesAsWritten = Args.getAllArgValues(OPT_target_feature);
|
2010-08-12 07:07:42 +08:00
|
|
|
Opts.LinkerVersion = Args.getLastArgValue(OPT_target_linker_version);
|
2010-08-30 17:42:39 +08:00
|
|
|
Opts.Triple = llvm::Triple::normalize(Args.getLastArgValue(OPT_triple));
|
2015-06-11 22:53:41 +08:00
|
|
|
Opts.Reciprocals = Args.getAllArgValues(OPT_mrecip_EQ);
|
2011-11-02 05:33:06 +08:00
|
|
|
// Use the default target triple if unspecified.
|
2009-12-01 11:16:53 +08:00
|
|
|
if (Opts.Triple.empty())
|
2011-11-02 05:33:06 +08:00
|
|
|
Opts.Triple = llvm::sys::getDefaultTargetTriple();
|
2014-01-14 03:48:18 +08:00
|
|
|
}
|
2009-12-01 11:16:53 +08:00
|
|
|
|
2011-12-23 11:05:38 +08:00
|
|
|
bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,
|
2010-11-23 16:35:12 +08:00
|
|
|
const char *const *ArgBegin,
|
|
|
|
const char *const *ArgEnd,
|
2011-09-26 07:23:43 +08:00
|
|
|
DiagnosticsEngine &Diags) {
|
2011-12-23 11:05:38 +08:00
|
|
|
bool Success = true;
|
|
|
|
|
2009-12-01 11:16:53 +08:00
|
|
|
// Parse the arguments.
|
2014-03-08 04:03:18 +08:00
|
|
|
std::unique_ptr<OptTable> Opts(createDriverOptTable());
|
2013-08-03 04:16:22 +08:00
|
|
|
const unsigned IncludedFlagsBitmask = options::CC1Option;
|
2009-12-01 11:16:53 +08:00
|
|
|
unsigned MissingArgIndex, MissingArgCount;
|
2015-06-23 06:07:27 +08:00
|
|
|
InputArgList Args =
|
2015-06-21 14:32:36 +08:00
|
|
|
Opts->ParseArgs(llvm::makeArrayRef(ArgBegin, ArgEnd), MissingArgIndex,
|
2015-06-23 06:07:27 +08:00
|
|
|
MissingArgCount, IncludedFlagsBitmask);
|
2016-04-09 01:42:32 +08:00
|
|
|
LangOptions &LangOpts = *Res.getLangOpts();
|
2009-12-01 11:16:53 +08:00
|
|
|
|
|
|
|
// Check for missing argument error.
|
2011-12-23 11:05:38 +08:00
|
|
|
if (MissingArgCount) {
|
2009-12-01 11:16:53 +08:00
|
|
|
Diags.Report(diag::err_drv_missing_argument)
|
2015-06-23 06:07:27 +08:00
|
|
|
<< Args.getArgString(MissingArgIndex) << MissingArgCount;
|
2011-12-23 11:05:38 +08:00
|
|
|
Success = false;
|
|
|
|
}
|
2009-12-01 11:16:53 +08:00
|
|
|
|
|
|
|
// Issue errors on unknown arguments.
|
2015-06-23 06:07:27 +08:00
|
|
|
for (const Arg *A : Args.filtered(OPT_UNKNOWN)) {
|
|
|
|
Diags.Report(diag::err_drv_unknown_argument) << A->getAsString(Args);
|
2011-12-23 11:05:38 +08:00
|
|
|
Success = false;
|
|
|
|
}
|
2009-12-01 11:16:53 +08:00
|
|
|
|
2015-06-23 06:07:27 +08:00
|
|
|
Success &= ParseAnalyzerArgs(*Res.getAnalyzerOpts(), Args, Diags);
|
|
|
|
Success &= ParseMigratorArgs(Res.getMigratorOpts(), Args);
|
|
|
|
ParseDependencyOutputArgs(Res.getDependencyOutputOpts(), Args);
|
2016-05-28 04:43:00 +08:00
|
|
|
Success &= ParseDiagnosticArgs(Res.getDiagnosticOpts(), Args, &Diags,
|
|
|
|
false /*DefaultDiagColor*/);
|
2016-04-09 01:42:32 +08:00
|
|
|
ParseCommentArgs(LangOpts.CommentOpts, Args);
|
2015-06-23 06:07:27 +08:00
|
|
|
ParseFileSystemArgs(Res.getFileSystemOpts(), Args);
|
2010-12-04 09:50:36 +08:00
|
|
|
// FIXME: We shouldn't have to pass the DashX option around here
|
2015-06-23 06:07:27 +08:00
|
|
|
InputKind DashX = ParseFrontendArgs(Res.getFrontendOpts(), Args, Diags);
|
2016-04-09 00:52:05 +08:00
|
|
|
ParseTargetArgs(Res.getTargetOpts(), Args, Diags);
|
2015-06-23 06:07:27 +08:00
|
|
|
Success &= ParseCodeGenArgs(Res.getCodeGenOpts(), Args, DashX, Diags,
|
2015-06-09 08:47:20 +08:00
|
|
|
Res.getTargetOpts());
|
2015-06-23 06:07:27 +08:00
|
|
|
ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), Args);
|
2015-07-18 04:09:56 +08:00
|
|
|
if (DashX == IK_AST || DashX == IK_LLVM_IR) {
|
|
|
|
// ObjCAAutoRefCount and Sanitize LangOpts are used to setup the
|
|
|
|
// PassManager in BackendUtil.cpp. They need to be initializd no matter
|
|
|
|
// what the input type is.
|
|
|
|
if (Args.hasArg(OPT_fobjc_arc))
|
2016-04-09 01:42:32 +08:00
|
|
|
LangOpts.ObjCAutoRefCount = 1;
|
|
|
|
// PIClevel and PIELevel are needed during code generation and this should be
|
|
|
|
// set regardless of the input type.
|
|
|
|
LangOpts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
|
|
|
|
LangOpts.PIELevel = getLastArgIntValue(Args, OPT_pie_level, 0, Diags);
|
2015-07-18 04:09:56 +08:00
|
|
|
parseSanitizerKinds("-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ),
|
2016-04-09 01:42:32 +08:00
|
|
|
Diags, LangOpts.Sanitize);
|
2015-07-18 04:09:56 +08:00
|
|
|
} else {
|
|
|
|
// Other LangOpts are only initialzed when the input is not AST or LLVM IR.
|
2016-04-09 01:42:32 +08:00
|
|
|
ParseLangArgs(LangOpts, Args, DashX, Res.getTargetOpts(), Diags);
|
2011-02-26 01:24:55 +08:00
|
|
|
if (Res.getFrontendOpts().ProgramAction == frontend::RewriteObjC)
|
2016-04-09 01:42:32 +08:00
|
|
|
LangOpts.ObjCExceptions = 1;
|
2011-02-26 01:24:55 +08:00
|
|
|
}
|
2016-03-14 21:23:58 +08:00
|
|
|
|
2016-05-20 02:44:45 +08:00
|
|
|
if (LangOpts.CUDA) {
|
|
|
|
// During CUDA device-side compilation, the aux triple is the
|
|
|
|
// triple used for host compilation.
|
|
|
|
if (LangOpts.CUDAIsDevice)
|
|
|
|
Res.getTargetOpts().HostTriple = Res.getFrontendOpts().AuxTriple;
|
|
|
|
|
|
|
|
// Set default FP_CONTRACT to FAST.
|
|
|
|
if (!Args.hasArg(OPT_ffp_contract))
|
|
|
|
Res.getCodeGenOpts().setFPContractMode(CodeGenOptions::FPC_Fast);
|
2016-04-30 07:05:19 +08:00
|
|
|
}
|
|
|
|
|
2016-03-15 17:41:39 +08:00
|
|
|
// FIXME: Override value name discarding when asan or msan is used because the
|
2016-03-14 21:23:58 +08:00
|
|
|
// backend passes depend on the name of the alloca in order to print out
|
|
|
|
// names.
|
2016-03-15 17:41:39 +08:00
|
|
|
Res.getCodeGenOpts().DiscardValueNames &=
|
2016-04-09 01:42:32 +08:00
|
|
|
!LangOpts.Sanitize.has(SanitizerKind::Address) &&
|
|
|
|
!LangOpts.Sanitize.has(SanitizerKind::Memory);
|
2016-03-14 21:23:58 +08:00
|
|
|
|
2010-11-04 06:45:23 +08:00
|
|
|
// FIXME: ParsePreprocessorArgs uses the FileManager to read the contents of
|
|
|
|
// PCH file and find the original header name. Remove the need to do that in
|
2015-08-05 23:08:53 +08:00
|
|
|
// ParsePreprocessorArgs and remove the FileManager
|
2010-11-04 06:45:23 +08:00
|
|
|
// parameters from the function and the "FileManager.h" #include.
|
2010-11-23 15:51:02 +08:00
|
|
|
FileManager FileMgr(Res.getFileSystemOpts());
|
2015-06-23 06:07:27 +08:00
|
|
|
ParsePreprocessorArgs(Res.getPreprocessorOpts(), Args, FileMgr, Diags);
|
|
|
|
ParsePreprocessorOutputArgs(Res.getPreprocessorOutputOpts(), Args,
|
2013-01-30 09:52:57 +08:00
|
|
|
Res.getFrontendOpts().ProgramAction);
|
2011-12-23 11:05:38 +08:00
|
|
|
return Success;
|
2009-12-01 11:16:53 +08:00
|
|
|
}
|
2011-09-14 07:15:45 +08:00
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
class ModuleSignature {
|
2013-01-13 03:30:44 +08:00
|
|
|
SmallVector<uint64_t, 16> Data;
|
2011-09-14 07:15:45 +08:00
|
|
|
unsigned CurBit;
|
|
|
|
uint64_t CurValue;
|
2015-08-05 23:08:53 +08:00
|
|
|
|
2011-09-14 07:15:45 +08:00
|
|
|
public:
|
|
|
|
ModuleSignature() : CurBit(0), CurValue(0) { }
|
2015-08-05 23:08:53 +08:00
|
|
|
|
2011-09-14 07:15:45 +08:00
|
|
|
void add(uint64_t Value, unsigned Bits);
|
|
|
|
void add(StringRef Value);
|
|
|
|
void flush();
|
2015-08-05 23:08:53 +08:00
|
|
|
|
2011-09-14 07:15:45 +08:00
|
|
|
llvm::APInt getAsInteger() const;
|
|
|
|
};
|
2015-06-23 07:07:51 +08:00
|
|
|
}
|
2011-09-14 07:15:45 +08:00
|
|
|
|
|
|
|
void ModuleSignature::add(uint64_t Value, unsigned int NumBits) {
|
|
|
|
CurValue |= Value << CurBit;
|
|
|
|
if (CurBit + NumBits < 64) {
|
|
|
|
CurBit += NumBits;
|
|
|
|
return;
|
|
|
|
}
|
2015-08-05 23:08:53 +08:00
|
|
|
|
2011-09-14 07:15:45 +08:00
|
|
|
// Add the current word.
|
|
|
|
Data.push_back(CurValue);
|
2015-08-05 23:08:53 +08:00
|
|
|
|
2011-09-14 07:15:45 +08:00
|
|
|
if (CurBit)
|
|
|
|
CurValue = Value >> (64-CurBit);
|
|
|
|
else
|
|
|
|
CurValue = 0;
|
|
|
|
CurBit = (CurBit+NumBits) & 63;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ModuleSignature::flush() {
|
|
|
|
if (CurBit == 0)
|
|
|
|
return;
|
2015-08-05 23:08:53 +08:00
|
|
|
|
2011-09-14 07:15:45 +08:00
|
|
|
Data.push_back(CurValue);
|
|
|
|
CurBit = 0;
|
|
|
|
CurValue = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ModuleSignature::add(StringRef Value) {
|
2015-10-17 14:46:39 +08:00
|
|
|
for (auto &c : Value)
|
|
|
|
add(c, 8);
|
2011-09-14 07:15:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
llvm::APInt ModuleSignature::getAsInteger() const {
|
|
|
|
return llvm::APInt(Data.size() * 64, Data);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string CompilerInvocation::getModuleHash() const {
|
2013-03-28 00:47:18 +08:00
|
|
|
// Note: For QoI reasons, the things we use as a hash here should all be
|
|
|
|
// dumped via the -module-info flag.
|
2012-11-06 03:45:09 +08:00
|
|
|
using llvm::hash_code;
|
|
|
|
using llvm::hash_value;
|
|
|
|
using llvm::hash_combine;
|
|
|
|
|
2011-09-14 07:15:45 +08:00
|
|
|
// Start the signature with the compiler version.
|
2012-11-06 07:30:26 +08:00
|
|
|
// FIXME: We'd rather use something more cryptographically sound than
|
2012-11-06 03:45:09 +08:00
|
|
|
// CityHash, but this will do for now.
|
|
|
|
hash_code code = hash_value(getClangFullRepositoryVersion());
|
|
|
|
|
2011-09-14 07:15:45 +08:00
|
|
|
// Extend the signature with the language options
|
|
|
|
#define LANGOPT(Name, Bits, Default, Description) \
|
2012-11-06 03:45:09 +08:00
|
|
|
code = hash_combine(code, LangOpts->Name);
|
2011-09-14 07:15:45 +08:00
|
|
|
#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
|
2012-11-06 03:45:09 +08:00
|
|
|
code = hash_combine(code, static_cast<unsigned>(LangOpts->get##Name()));
|
2011-09-14 07:15:45 +08:00
|
|
|
#define BENIGN_LANGOPT(Name, Bits, Default, Description)
|
|
|
|
#define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description)
|
|
|
|
#include "clang/Basic/LangOptions.def"
|
2015-06-24 02:20:18 +08:00
|
|
|
|
|
|
|
for (StringRef Feature : LangOpts->ModuleFeatures)
|
|
|
|
code = hash_combine(code, Feature);
|
2015-08-05 23:08:53 +08:00
|
|
|
|
2012-11-06 03:45:09 +08:00
|
|
|
// Extend the signature with the target options.
|
|
|
|
code = hash_combine(code, TargetOpts->Triple, TargetOpts->CPU,
|
2014-04-30 02:45:01 +08:00
|
|
|
TargetOpts->ABI);
|
2012-11-06 03:45:09 +08:00
|
|
|
for (unsigned i = 0, n = TargetOpts->FeaturesAsWritten.size(); i != n; ++i)
|
|
|
|
code = hash_combine(code, TargetOpts->FeaturesAsWritten[i]);
|
2011-09-14 07:15:45 +08:00
|
|
|
|
2011-09-14 23:55:12 +08:00
|
|
|
// Extend the signature with preprocessor options.
|
2012-11-06 03:45:09 +08:00
|
|
|
const PreprocessorOptions &ppOpts = getPreprocessorOpts();
|
2013-02-07 08:21:12 +08:00
|
|
|
const HeaderSearchOptions &hsOpts = getHeaderSearchOpts();
|
2012-11-06 03:45:09 +08:00
|
|
|
code = hash_combine(code, ppOpts.UsePredefines, ppOpts.DetailedRecord);
|
|
|
|
|
2015-08-05 23:08:53 +08:00
|
|
|
for (std::vector<std::pair<std::string, bool/*isUndef*/>>::const_iterator
|
2011-10-17 22:55:37 +08:00
|
|
|
I = getPreprocessorOpts().Macros.begin(),
|
|
|
|
IEnd = getPreprocessorOpts().Macros.end();
|
|
|
|
I != IEnd; ++I) {
|
2013-02-07 08:21:12 +08:00
|
|
|
// If we're supposed to ignore this macro for the purposes of modules,
|
|
|
|
// don't put it into the hash.
|
|
|
|
if (!hsOpts.ModulesIgnoreMacros.empty()) {
|
|
|
|
// Check whether we're ignoring this macro.
|
2013-02-07 09:18:48 +08:00
|
|
|
StringRef MacroDef = I->first;
|
|
|
|
if (hsOpts.ModulesIgnoreMacros.count(MacroDef.split('=').first))
|
2013-02-07 08:21:12 +08:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2012-11-06 03:45:09 +08:00
|
|
|
code = hash_combine(code, I->first, I->second);
|
2011-10-17 22:55:37 +08:00
|
|
|
}
|
2012-11-06 03:45:09 +08:00
|
|
|
|
2016-01-13 05:01:56 +08:00
|
|
|
// Extend the signature with the sysroot and other header search options.
|
|
|
|
code = hash_combine(code, hsOpts.Sysroot,
|
|
|
|
hsOpts.ModuleFormat,
|
|
|
|
hsOpts.UseDebugInfo,
|
|
|
|
hsOpts.UseBuiltinIncludes,
|
2012-11-06 03:45:09 +08:00
|
|
|
hsOpts.UseStandardSystemIncludes,
|
|
|
|
hsOpts.UseStandardCXXIncludes,
|
|
|
|
hsOpts.UseLibcxx);
|
2014-05-04 13:27:24 +08:00
|
|
|
code = hash_combine(code, hsOpts.ResourceDir);
|
2012-11-06 03:45:09 +08:00
|
|
|
|
2014-03-03 16:12:05 +08:00
|
|
|
// Extend the signature with the user build path.
|
|
|
|
code = hash_combine(code, hsOpts.ModuleUserBuildPath);
|
|
|
|
|
2015-11-04 02:33:07 +08:00
|
|
|
// Extend the signature with the module file extensions.
|
|
|
|
const FrontendOptions &frontendOpts = getFrontendOpts();
|
2016-05-27 21:36:58 +08:00
|
|
|
for (const auto &ext : frontendOpts.ModuleFileExtensions) {
|
2015-11-04 02:33:07 +08:00
|
|
|
code = ext->hashExtension(code);
|
|
|
|
}
|
|
|
|
|
2013-05-11 05:54:08 +08:00
|
|
|
// Darwin-specific hack: if we have a sysroot, use the contents and
|
|
|
|
// modification time of
|
2013-04-12 08:18:53 +08:00
|
|
|
// $sysroot/System/Library/CoreServices/SystemVersion.plist
|
|
|
|
// as part of the module hash.
|
|
|
|
if (!hsOpts.Sysroot.empty()) {
|
|
|
|
SmallString<128> systemVersionFile;
|
|
|
|
systemVersionFile += hsOpts.Sysroot;
|
|
|
|
llvm::sys::path::append(systemVersionFile, "System");
|
|
|
|
llvm::sys::path::append(systemVersionFile, "Library");
|
|
|
|
llvm::sys::path::append(systemVersionFile, "CoreServices");
|
|
|
|
llvm::sys::path::append(systemVersionFile, "SystemVersion.plist");
|
2014-07-07 01:43:24 +08:00
|
|
|
|
|
|
|
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> buffer =
|
2015-03-18 18:17:07 +08:00
|
|
|
llvm::MemoryBuffer::getFile(systemVersionFile);
|
2014-07-07 01:43:24 +08:00
|
|
|
if (buffer) {
|
2013-04-12 08:18:53 +08:00
|
|
|
code = hash_combine(code, buffer.get()->getBuffer());
|
2013-05-11 05:54:08 +08:00
|
|
|
|
|
|
|
struct stat statBuf;
|
|
|
|
if (stat(systemVersionFile.c_str(), &statBuf) == 0)
|
|
|
|
code = hash_combine(code, statBuf.st_mtime);
|
2013-04-12 08:18:53 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-06 03:45:09 +08:00
|
|
|
return llvm::APInt(64, code).toString(36, /*Signed=*/false);
|
2011-09-14 07:15:45 +08:00
|
|
|
}
|
2013-06-15 01:17:23 +08:00
|
|
|
|
|
|
|
namespace clang {
|
|
|
|
|
Add an option to allow Clang verify source files for a module only once during
the build
When Clang loads the module, it verifies the user source files that the module
was built from. If any file was changed, the module is rebuilt. There are two
problems with this:
1. correctness: we don't verify system files (there are too many of them, and
stat'ing all of them would take a lot of time);
2. performance: the same module file is verified again and again during a
single build.
This change allows the build system to optimize source file verification. The
idea is based on the fact that while the project is being built, the source
files don't change. This allows us to verify the module only once during a
single build session. The build system passes a flag,
-fbuild-session-timestamp=, to inform Clang of the time when the build started.
The build system also requests to enable this feature by passing
-fmodules-validate-once-per-build-session. If these flags are not passed, the
behavior is not changed. When Clang verifies the module the first time, it
writes out a timestamp file. Then, when Clang loads the module the second
time, it finds a timestamp file, so it can compare the verification timestamp
of the module with the time when the build started. If the verification
timestamp is too old, the module is verified again, and the timestamp file is
updated.
llvm-svn: 201224
2014-02-12 18:33:14 +08:00
|
|
|
template<typename IntTy>
|
|
|
|
static IntTy getLastArgIntValueImpl(const ArgList &Args, OptSpecifier Id,
|
|
|
|
IntTy Default,
|
|
|
|
DiagnosticsEngine *Diags) {
|
|
|
|
IntTy Res = Default;
|
2013-06-15 01:17:23 +08:00
|
|
|
if (Arg *A = Args.getLastArg(Id)) {
|
|
|
|
if (StringRef(A->getValue()).getAsInteger(10, Res)) {
|
|
|
|
if (Diags)
|
|
|
|
Diags->Report(diag::err_drv_invalid_int_value) << A->getAsString(Args)
|
|
|
|
<< A->getValue();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return Res;
|
|
|
|
}
|
2013-12-27 16:11:08 +08:00
|
|
|
|
Add an option to allow Clang verify source files for a module only once during
the build
When Clang loads the module, it verifies the user source files that the module
was built from. If any file was changed, the module is rebuilt. There are two
problems with this:
1. correctness: we don't verify system files (there are too many of them, and
stat'ing all of them would take a lot of time);
2. performance: the same module file is verified again and again during a
single build.
This change allows the build system to optimize source file verification. The
idea is based on the fact that while the project is being built, the source
files don't change. This allows us to verify the module only once during a
single build session. The build system passes a flag,
-fbuild-session-timestamp=, to inform Clang of the time when the build started.
The build system also requests to enable this feature by passing
-fmodules-validate-once-per-build-session. If these flags are not passed, the
behavior is not changed. When Clang verifies the module the first time, it
writes out a timestamp file. Then, when Clang loads the module the second
time, it finds a timestamp file, so it can compare the verification timestamp
of the module with the time when the build started. If the verification
timestamp is too old, the module is verified again, and the timestamp file is
updated.
llvm-svn: 201224
2014-02-12 18:33:14 +08:00
|
|
|
|
|
|
|
// Declared in clang/Frontend/Utils.h.
|
|
|
|
int getLastArgIntValue(const ArgList &Args, OptSpecifier Id, int Default,
|
|
|
|
DiagnosticsEngine *Diags) {
|
|
|
|
return getLastArgIntValueImpl<int>(Args, Id, Default, Diags);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t getLastArgUInt64Value(const ArgList &Args, OptSpecifier Id,
|
|
|
|
uint64_t Default,
|
|
|
|
DiagnosticsEngine *Diags) {
|
|
|
|
return getLastArgIntValueImpl<uint64_t>(Args, Id, Default, Diags);
|
|
|
|
}
|
|
|
|
|
2013-12-27 16:11:08 +08:00
|
|
|
void BuryPointer(const void *Ptr) {
|
|
|
|
// This function may be called only a small fixed amount of times per each
|
|
|
|
// invocation, otherwise we do actually have a leak which we want to report.
|
|
|
|
// If this function is called more than kGraveYardMaxSize times, the pointers
|
|
|
|
// will not be properly buried and a leak detector will report a leak, which
|
|
|
|
// is what we want in such case.
|
|
|
|
static const size_t kGraveYardMaxSize = 16;
|
2013-12-28 10:50:00 +08:00
|
|
|
LLVM_ATTRIBUTE_UNUSED static const void *GraveYard[kGraveYardMaxSize];
|
2014-03-03 01:08:31 +08:00
|
|
|
static std::atomic<unsigned> GraveYardSize;
|
|
|
|
unsigned Idx = GraveYardSize++;
|
2013-12-27 16:11:08 +08:00
|
|
|
if (Idx >= kGraveYardMaxSize)
|
|
|
|
return;
|
|
|
|
GraveYard[Idx] = Ptr;
|
|
|
|
}
|
2014-04-16 02:16:25 +08:00
|
|
|
|
|
|
|
IntrusiveRefCntPtr<vfs::FileSystem>
|
|
|
|
createVFSFromCompilerInvocation(const CompilerInvocation &CI,
|
|
|
|
DiagnosticsEngine &Diags) {
|
|
|
|
if (CI.getHeaderSearchOpts().VFSOverlayFiles.empty())
|
|
|
|
return vfs::getRealFileSystem();
|
|
|
|
|
|
|
|
IntrusiveRefCntPtr<vfs::OverlayFileSystem>
|
|
|
|
Overlay(new vfs::OverlayFileSystem(vfs::getRealFileSystem()));
|
|
|
|
// earlier vfs files are on the bottom
|
|
|
|
for (const std::string &File : CI.getHeaderSearchOpts().VFSOverlayFiles) {
|
2014-07-07 01:43:24 +08:00
|
|
|
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buffer =
|
|
|
|
llvm::MemoryBuffer::getFile(File);
|
|
|
|
if (!Buffer) {
|
2014-04-16 02:16:25 +08:00
|
|
|
Diags.Report(diag::err_missing_vfs_overlay_file) << File;
|
|
|
|
return IntrusiveRefCntPtr<vfs::FileSystem>();
|
|
|
|
}
|
|
|
|
|
Reapply [2] [VFS] Add 'overlay-relative' field to YAML files
This reapplies r261552 and r263748. Fixed testcase to reapply.
The VFS overlay mapping between virtual paths and real paths is done through
the 'external-contents' entries in YAML files, which contains hardcoded paths
to the real files.
When a module compilation crashes, headers are dumped into <name>.cache/vfs
directory and are mapped via the <name>.cache/vfs/vfs.yaml. The script
generated for reproduction uses -ivfsoverlay pointing to file to gather the
mapping between virtual paths and files inside <name>.cache/vfs. Currently, we
are only capable of reproducing such crashes in the same machine as they
happen, because of the hardcoded paths in 'external-contents'.
To be able to reproduce a crash in another machine, this patch introduces a new
option in the VFS yaml file called 'overlay-relative'. When it's equal to
'true' it means that the provided path to the YAML file through the
-ivfsoverlay option should also be used to prefix the final path for every
'external-contents'.
Example, given the invocation snippet "... -ivfsoverlay
<name>.cache/vfs/vfs.yaml" and the following entry in the yaml file:
"overlay-relative": "true",
"roots": [
...
"type": "directory",
"name": "/usr/include",
"contents": [
{
"type": "file",
"name": "stdio.h",
"external-contents": "/usr/include/stdio.h"
},
...
Here, a file manager request for virtual "/usr/include/stdio.h", that will map
into real path "/<absolute_path_to>/<name>.cache/vfs/usr/include/stdio.h.
This is a useful feature for debugging module crashes in machines other than
the one where the error happened.
Differential Revision: http://reviews.llvm.org/D17457
rdar://problem/24499339
llvm-svn: 263893
2016-03-20 10:08:48 +08:00
|
|
|
IntrusiveRefCntPtr<vfs::FileSystem> FS = vfs::getVFSFromYAML(
|
|
|
|
std::move(Buffer.get()), /*DiagHandler*/ nullptr, File);
|
2014-07-05 11:08:06 +08:00
|
|
|
if (!FS.get()) {
|
2014-04-16 02:16:25 +08:00
|
|
|
Diags.Report(diag::err_invalid_vfs_overlay) << File;
|
|
|
|
return IntrusiveRefCntPtr<vfs::FileSystem>();
|
|
|
|
}
|
|
|
|
Overlay->pushOverlay(FS);
|
|
|
|
}
|
|
|
|
return Overlay;
|
2013-06-15 01:17:23 +08:00
|
|
|
}
|
2014-04-16 02:16:25 +08:00
|
|
|
} // end namespace clang
|