2009-11-17 14:02:29 +08:00
|
|
|
//===--- CompilerInvocation.cpp -------------------------------------------===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2012-12-22 01:23:52 +08:00
|
|
|
#include "clang/Frontend/CompilerInvocation.h"
|
2009-12-01 11:16:53 +08:00
|
|
|
#include "clang/Basic/Diagnostic.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"
|
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"
|
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"
|
2012-11-06 03:45:09 +08:00
|
|
|
#include "llvm/ADT/Hashing.h"
|
2009-12-01 11:16:53 +08:00
|
|
|
#include "llvm/ADT/OwningPtr.h"
|
|
|
|
#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"
|
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"
|
2013-12-27 16:11:08 +08:00
|
|
|
#include "llvm/Support/Atomic.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"
|
2013-04-12 08:18:53 +08:00
|
|
|
#include "llvm/Support/system_error.h"
|
2013-05-11 05:54:08 +08:00
|
|
|
#include <sys/stat.h>
|
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>(),
|
2012-10-17 07:40:58 +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
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void addWarningArgs(ArgList &Args, std::vector<std::string> &Warnings) {
|
|
|
|
for (arg_iterator I = Args.filtered_begin(OPT_W_Group),
|
|
|
|
E = Args.filtered_end(); I != E; ++I) {
|
|
|
|
Arg *A = *I;
|
2012-10-23 06:13:48 +08:00
|
|
|
// If the argument is a pure flag, add its name (minus the "W" at the beginning)
|
2012-05-01 22:57:16 +08:00
|
|
|
// to the warning list. Else, add its value (for the OPT_W case).
|
|
|
|
if (A->getOption().getKind() == Option::FlagClass) {
|
2012-10-23 06:13:48 +08:00
|
|
|
Warnings.push_back(A->getOption().getName().substr(1));
|
2012-05-01 22:57:16 +08:00
|
|
|
} else {
|
|
|
|
for (unsigned Idx = 0, End = A->getNumValues();
|
|
|
|
Idx < End; ++Idx) {
|
2012-11-01 12:30:05 +08:00
|
|
|
StringRef V = A->getValue(Idx);
|
2012-05-01 22:57:16 +08:00
|
|
|
// "-Wl," and such are not warning options.
|
|
|
|
// FIXME: Should be handled by putting these in separate flags.
|
|
|
|
if (V.startswith("l,") || V.startswith("a,") || V.startswith("p,"))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
Warnings.push_back(V);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-12-04 09:50:36 +08:00
|
|
|
}
|
|
|
|
|
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);
|
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();
|
|
|
|
for (arg_iterator it = Args.filtered_begin(OPT_analyzer_checker,
|
|
|
|
OPT_analyzer_disable_checker),
|
|
|
|
ie = Args.filtered_end(); it != ie; ++it) {
|
|
|
|
const Arg *A = *it;
|
|
|
|
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, ",");
|
|
|
|
for (unsigned i = 0, e = checkers.size(); i != e; ++i)
|
|
|
|
Opts.CheckersControlList.push_back(std::make_pair(checkers[i], enable));
|
2011-02-15 02:13:31 +08:00
|
|
|
}
|
2012-08-29 13:55:00 +08:00
|
|
|
|
|
|
|
// Go through the analyzer configuration options.
|
|
|
|
for (arg_iterator it = Args.filtered_begin(OPT_analyzer_config),
|
|
|
|
ie = Args.filtered_end(); it != ie; ++it) {
|
|
|
|
const Arg *A = *it;
|
|
|
|
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;
|
2012-08-30 13:49:16 +08:00
|
|
|
llvm::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
|
|
|
}
|
|
|
|
|
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;
|
2010-12-04 09:50:36 +08:00
|
|
|
|
2013-11-18 21:23:07 +08:00
|
|
|
Opts.OptimizationLevel = getOptimizationLevel(Args, IK, Diags);
|
|
|
|
// TODO: This could be done in Driver
|
|
|
|
unsigned MaxOptLevel = 3;
|
|
|
|
if (Opts.OptimizationLevel > MaxOptLevel) {
|
|
|
|
// If the optimization level is not supported, fall back on the default optimization
|
|
|
|
Diags.Report(diag::warn_drv_optimization_value)
|
|
|
|
<< Args.getLastArg(OPT_O)->getAsString(Args) << "-O" << MaxOptLevel;
|
|
|
|
Opts.OptimizationLevel = MaxOptLevel;
|
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);
|
2012-10-24 04:05:01 +08:00
|
|
|
Opts.setInlining(Args.hasArg(OPT_fno_inline_functions) ?
|
|
|
|
CodeGenOptions::OnlyAlwaysInlining : Opts.getInlining());
|
2009-12-01 11:16:53 +08:00
|
|
|
|
2012-05-04 15:39:27 +08:00
|
|
|
if (Args.hasArg(OPT_gline_tables_only)) {
|
2012-10-24 04:05:01 +08:00
|
|
|
Opts.setDebugInfo(CodeGenOptions::DebugLineTablesOnly);
|
2013-06-19 09:46:49 +08:00
|
|
|
} else if (Args.hasArg(OPT_g_Flag) || Args.hasArg(OPT_gdwarf_2) ||
|
|
|
|
Args.hasArg(OPT_gdwarf_3) || Args.hasArg(OPT_gdwarf_4)) {
|
2014-01-07 09:19:08 +08:00
|
|
|
bool Default = false;
|
|
|
|
// Until dtrace (via CTF) can deal with distributed debug info,
|
|
|
|
// Darwin defaults to standalone/full debug info.
|
|
|
|
if (llvm::Triple(TargetOpts.Triple).isOSDarwin())
|
|
|
|
Default = true;
|
|
|
|
|
|
|
|
if (Args.hasFlag(OPT_fstandalone_debug, OPT_fno_standalone_debug, Default))
|
2012-10-24 04:05:01 +08:00
|
|
|
Opts.setDebugInfo(CodeGenOptions::FullDebugInfo);
|
2014-01-07 09:19:08 +08:00
|
|
|
else
|
|
|
|
Opts.setDebugInfo(CodeGenOptions::LimitedDebugInfo);
|
2012-04-27 15:24:20 +08:00
|
|
|
}
|
2012-10-19 05:52:18 +08:00
|
|
|
Opts.DebugColumnInfo = Args.hasArg(OPT_dwarf_column_info);
|
2013-02-23 07:50:16 +08:00
|
|
|
Opts.SplitDwarfFile = Args.getLastArgValue(OPT_split_dwarf_file);
|
2013-06-19 09:46:49 +08:00
|
|
|
if (Args.hasArg(OPT_gdwarf_2))
|
|
|
|
Opts.DwarfVersion = 2;
|
|
|
|
else if (Args.hasArg(OPT_gdwarf_3))
|
|
|
|
Opts.DwarfVersion = 3;
|
|
|
|
else if (Args.hasArg(OPT_gdwarf_4))
|
|
|
|
Opts.DwarfVersion = 4;
|
|
|
|
else if (Opts.getDebugInfo() != CodeGenOptions::NoDebugInfo)
|
2013-09-04 00:10:12 +08:00
|
|
|
// Default Dwarf version is 4 if we are generating debug information.
|
|
|
|
Opts.DwarfVersion = 4;
|
2012-04-27 15:24:20 +08:00
|
|
|
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.DisableLLVMOpts = Args.hasArg(OPT_disable_llvm_optzns);
|
|
|
|
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));
|
2013-08-08 16:34:35 +08:00
|
|
|
Opts.UnrollLoops =
|
|
|
|
Args.hasFlag(OPT_funroll_loops, OPT_fno_unroll_loops,
|
|
|
|
(Opts.OptimizationLevel > 1 && !Opts.OptimizeSize));
|
2013-11-18 00:03:29 +08:00
|
|
|
Opts.RerollLoops = Args.hasArg(OPT_freroll_loops);
|
2009-12-01 11:16:53 +08:00
|
|
|
|
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);
|
2014-01-07 06:27:36 +08:00
|
|
|
Opts.ProfileInstrGenerate = Args.hasArg(OPT_fprofile_instr_generate);
|
|
|
|
Opts.InstrProfileInput = Args.getLastArgValue(OPT_fprofile_instr_use_EQ);
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.AsmVerbose = Args.hasArg(OPT_masm_verbose);
|
2011-06-16 07:02:42 +08:00
|
|
|
Opts.ObjCAutoRefCountExceptions = Args.hasArg(OPT_fobjc_arc_exceptions);
|
2011-10-07 02:29:46 +08:00
|
|
|
Opts.CUDAIsDevice = Args.hasArg(OPT_fcuda_is_device);
|
2010-03-20 12:15:41 +08:00
|
|
|
Opts.CXAAtExit = !Args.hasArg(OPT_fno_use_cxa_atexit);
|
|
|
|
Opts.CXXCtorDtorAliases = Args.hasArg(OPT_mconstructor_aliases);
|
2010-05-21 00:54:55 +08:00
|
|
|
Opts.CodeModel = Args.getLastArgValue(OPT_mcode_model);
|
|
|
|
Opts.DebugPass = Args.getLastArgValue(OPT_mdebug_pass);
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.DisableFPElim = Args.hasArg(OPT_mdisable_fp_elim);
|
2013-06-22 05:15:32 +08:00
|
|
|
Opts.DisableFree = Args.hasArg(OPT_disable_free);
|
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-08-13 07:36:15 +08:00
|
|
|
Opts.HiddenWeakVTables = Args.hasArg(OPT_fhidden_weak_vtables);
|
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) ||
|
|
|
|
Args.hasArg(OPT_cl_finite_math_only)||
|
|
|
|
Args.hasArg(OPT_cl_fast_relaxed_math));
|
|
|
|
Opts.NoNaNsFPMath = (Args.hasArg(OPT_menable_no_nans) ||
|
|
|
|
Args.hasArg(OPT_cl_finite_math_only)||
|
|
|
|
Args.hasArg(OPT_cl_fast_relaxed_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-08-26 08:26:29 +08:00
|
|
|
Opts.NoGlobalMerge = Args.hasArg(OPT_mno_global_merge);
|
2011-06-21 08:14:18 +08:00
|
|
|
Opts.NoExecStack = Args.hasArg(OPT_mno_exec_stack);
|
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);
|
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-05-01 02:35:43 +08:00
|
|
|
Opts.NoDwarf2CFIAsm = Args.hasArg(OPT_fno_dwarf2_cfi_asm);
|
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);
|
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");
|
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);
|
2010-04-13 08:38:24 +08:00
|
|
|
|
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);
|
2012-12-31 04:53:28 +08:00
|
|
|
Opts.SanitizeRecover = !Args.hasArg(OPT_fno_sanitize_recover);
|
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) {
|
2011-05-05 08:08:20 +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);
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Opts.InstrumentFunctions = Args.hasArg(OPT_finstrument_functions);
|
|
|
|
Opts.InstrumentForProfiling = Args.hasArg(OPT_pg);
|
|
|
|
Opts.EmitOpenCLArgMetadata = Args.hasArg(OPT_cl_kernel_arg_info);
|
2011-10-21 10:32:14 +08:00
|
|
|
Opts.DebugCompilationDir = Args.getLastArgValue(OPT_fdebug_compilation_dir);
|
2011-10-31 01:30:44 +08:00
|
|
|
Opts.LinkBitcodeFile = Args.getLastArgValue(OPT_mlink_bitcode_file);
|
2012-12-04 03:12:58 +08:00
|
|
|
Opts.SanitizerBlacklistFile = Args.getLastArgValue(OPT_fsanitize_blacklist);
|
2013-01-20 21:12:12 +08:00
|
|
|
Opts.SanitizeMemoryTrackOrigins =
|
2012-12-24 16:42:34 +08:00
|
|
|
Args.hasArg(OPT_fsanitize_memory_track_origins);
|
2013-01-20 21:12:12 +08:00
|
|
|
Opts.SanitizeAddressZeroBaseShadow =
|
|
|
|
Args.hasArg(OPT_fsanitize_address_zero_base_shadow);
|
2013-01-30 07:31:22 +08:00
|
|
|
Opts.SanitizeUndefinedTrapOnError =
|
|
|
|
Args.hasArg(OPT_fsanitize_undefined_trap_on_error);
|
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
|
|
|
|
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
|
|
|
|
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);
|
|
|
|
|
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);
|
|
|
|
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);
|
2009-12-01 11:16:53 +08:00
|
|
|
}
|
|
|
|
|
2012-03-14 04:09:56 +08:00
|
|
|
bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
|
|
|
|
DiagnosticsEngine *Diags) {
|
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);
|
2011-10-29 08:12:39 +08:00
|
|
|
Opts.DiagnosticSerializationFile =
|
|
|
|
Args.getLastArgValue(OPT_diagnostic_serialized_file);
|
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);
|
|
|
|
Opts.ShowColors = Args.hasArg(OPT_fcolor_diagnostics);
|
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")
|
2012-10-24 07:11:23 +08:00
|
|
|
Opts.setFormat(DiagnosticOptions::Msvc);
|
2013-09-24 08:08:55 +08:00
|
|
|
else if (Format == "msvc-fallback") {
|
|
|
|
Opts.setFormat(DiagnosticOptions::Msvc);
|
|
|
|
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
|
|
|
}
|
2011-05-22 01:07:29 +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);
|
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);
|
|
|
|
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);
|
2012-05-01 22:57:16 +08:00
|
|
|
addWarningArgs(Args, Opts.Warnings);
|
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);
|
|
|
|
}
|
|
|
|
|
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:
|
|
|
|
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;
|
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)) {
|
2012-11-01 12:30:05 +08:00
|
|
|
Opts.Plugins.push_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();
|
2010-06-17 00:59:23 +08:00
|
|
|
|
|
|
|
for (arg_iterator it = Args.filtered_begin(OPT_plugin_arg),
|
|
|
|
end = Args.filtered_end(); it != end; ++it) {
|
2012-11-01 12:30:05 +08:00
|
|
|
if ((*it)->getValue(0) == Opts.ActionName)
|
|
|
|
Opts.PluginArgs.push_back((*it)->getValue(1));
|
2010-06-17 00:59:23 +08:00
|
|
|
}
|
2009-12-01 11:16:53 +08:00
|
|
|
}
|
|
|
|
|
2011-01-26 04:34:14 +08:00
|
|
|
Opts.AddPluginActions = Args.getAllArgValues(OPT_add_plugin);
|
2011-01-30 05:21:49 +08:00
|
|
|
Opts.AddPluginArgs.resize(Opts.AddPluginActions.size());
|
|
|
|
for (int i = 0, e = Opts.AddPluginActions.size(); i != e; ++i) {
|
|
|
|
for (arg_iterator it = Args.filtered_begin(OPT_plugin_arg),
|
|
|
|
end = Args.filtered_end(); it != end; ++it) {
|
2012-11-01 12:30:05 +08:00
|
|
|
if ((*it)->getValue(0) == Opts.AddPluginActions[i])
|
|
|
|
Opts.AddPluginArgs[i].push_back((*it)->getValue(1));
|
2011-01-30 05:21:49 +08:00
|
|
|
}
|
|
|
|
}
|
2011-01-26 04:34:14 +08:00
|
|
|
|
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);
|
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;
|
2013-01-24 06:38:11 +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);
|
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;
|
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)
|
|
|
|
.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;
|
|
|
|
}
|
2012-01-21 00:28:04 +08:00
|
|
|
Opts.Inputs.push_back(FrontendInputFile(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) {
|
2013-06-26 13:40:30 +08:00
|
|
|
SmallString<128> P(llvm::sys::fs::getMainExecutable(Argv0, MainAddr));
|
2009-12-01 11:16:53 +08:00
|
|
|
|
2013-06-26 13:40:30 +08:00
|
|
|
if (!P.empty()) {
|
|
|
|
llvm::sys::path::remove_filename(P); // Remove /clang from foo/bin/clang
|
|
|
|
llvm::sys::path::remove_filename(P); // Remove /bin from foo/bin
|
2009-12-01 11:16:53 +08:00
|
|
|
|
|
|
|
// Get foo/lib/clang/<version>/include
|
2013-06-29 00:25:46 +08:00
|
|
|
llvm::sys::path::append(P, "lib", "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);
|
2011-09-14 07:15:45 +08:00
|
|
|
Opts.DisableModuleHash = Args.hasArg(OPT_fdisable_module_hash);
|
2013-08-06 04:26:17 +08:00
|
|
|
// -fmodules implies -fmodule-maps
|
|
|
|
Opts.ModuleMaps = Args.hasArg(OPT_fmodule_maps) || Args.hasArg(OPT_fmodules);
|
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);
|
2013-02-07 08:21:12 +08:00
|
|
|
for (arg_iterator it = Args.filtered_begin(OPT_fmodules_ignore_macro),
|
2013-06-15 01:17:23 +08:00
|
|
|
ie = Args.filtered_end();
|
|
|
|
it != ie; ++it) {
|
2013-02-07 09:18:48 +08:00
|
|
|
StringRef MacroDef = (*it)->getValue();
|
|
|
|
Opts.ModulesIgnoreMacros.insert(MacroDef.split('=').first);
|
2013-02-07 08:21:12 +08:00
|
|
|
}
|
2013-09-24 17:27:13 +08:00
|
|
|
std::vector<std::string> ModuleMapFiles =
|
|
|
|
Args.getAllArgValues(OPT_fmodule_map_file);
|
|
|
|
Opts.ModuleMapFiles.insert(ModuleMapFiles.begin(), ModuleMapFiles.end());
|
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;
|
|
|
|
for (arg_iterator it = Args.filtered_begin(OPT_I, OPT_F,
|
|
|
|
OPT_index_header_map),
|
|
|
|
ie = Args.filtered_end(); it != ie; ++it) {
|
|
|
|
if ((*it)->getOption().matches(OPT_index_header_map)) {
|
|
|
|
// -index-header-map applies to the next -I or -F.
|
|
|
|
IsIndexHeaderMap = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
frontend::IncludeDirGroup Group
|
|
|
|
= IsIndexHeaderMap? frontend::IndexHeaderMap : frontend::Angled;
|
|
|
|
|
2013-01-25 09:50:47 +08:00
|
|
|
Opts.AddPath((*it)->getValue(), Group,
|
2013-01-30 07:59:45 +08:00
|
|
|
/*IsFramework=*/ (*it)->getOption().matches(OPT_F), 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.
|
2009-12-01 11:16:53 +08:00
|
|
|
for (arg_iterator it = Args.filtered_begin(OPT_iprefix, OPT_iwithprefix,
|
|
|
|
OPT_iwithprefixbefore),
|
|
|
|
ie = Args.filtered_end(); it != ie; ++it) {
|
2010-06-12 06:00:13 +08:00
|
|
|
const Arg *A = *it;
|
|
|
|
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))
|
2012-11-01 12:30:05 +08:00
|
|
|
Opts.AddPath(Prefix.str() + A->getValue(),
|
2013-01-30 07:59:45 +08:00
|
|
|
frontend::After, false, true);
|
2009-12-01 11:16:53 +08:00
|
|
|
else
|
2012-11-01 12:30:05 +08:00
|
|
|
Opts.AddPath(Prefix.str() + A->getValue(),
|
2013-01-30 07:59:45 +08:00
|
|
|
frontend::Angled, false, true);
|
2009-12-01 11:16:53 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
for (arg_iterator it = Args.filtered_begin(OPT_idirafter),
|
|
|
|
ie = Args.filtered_end(); it != ie; ++it)
|
2013-01-30 07:59:45 +08:00
|
|
|
Opts.AddPath((*it)->getValue(), frontend::After, false, true);
|
2009-12-01 11:16:53 +08:00
|
|
|
for (arg_iterator it = Args.filtered_begin(OPT_iquote),
|
|
|
|
ie = Args.filtered_end(); it != ie; ++it)
|
2013-01-30 07:59:45 +08:00
|
|
|
Opts.AddPath((*it)->getValue(), frontend::Quoted, false, true);
|
2011-09-23 05:41:16 +08:00
|
|
|
for (arg_iterator it = Args.filtered_begin(OPT_isystem,
|
2011-02-22 08:40:56 +08:00
|
|
|
OPT_iwithsysroot), ie = Args.filtered_end(); it != ie; ++it)
|
2013-01-25 09:50:47 +08:00
|
|
|
Opts.AddPath((*it)->getValue(), frontend::System, false,
|
2011-09-23 05:41:16 +08:00
|
|
|
!(*it)->getOption().matches(OPT_iwithsysroot));
|
2011-10-19 04:40:38 +08:00
|
|
|
for (arg_iterator it = Args.filtered_begin(OPT_iframework),
|
|
|
|
ie = Args.filtered_end(); it != ie; ++it)
|
2013-01-25 09:50:47 +08:00
|
|
|
Opts.AddPath((*it)->getValue(), frontend::System, true, true);
|
2011-09-23 05:41:16 +08:00
|
|
|
|
|
|
|
// Add the paths for the various language specific isystem flags.
|
|
|
|
for (arg_iterator it = Args.filtered_begin(OPT_c_isystem),
|
|
|
|
ie = Args.filtered_end(); it != ie; ++it)
|
2013-01-25 09:50:47 +08:00
|
|
|
Opts.AddPath((*it)->getValue(), frontend::CSystem, false, true);
|
2011-09-23 05:41:16 +08:00
|
|
|
for (arg_iterator it = Args.filtered_begin(OPT_cxx_isystem),
|
|
|
|
ie = Args.filtered_end(); it != ie; ++it)
|
2013-01-25 09:50:47 +08:00
|
|
|
Opts.AddPath((*it)->getValue(), frontend::CXXSystem, false, true);
|
2011-09-23 05:41:16 +08:00
|
|
|
for (arg_iterator it = Args.filtered_begin(OPT_objc_isystem),
|
|
|
|
ie = Args.filtered_end(); it != ie; ++it)
|
2013-01-25 09:50:47 +08:00
|
|
|
Opts.AddPath((*it)->getValue(), frontend::ObjCSystem, false,true);
|
2011-09-23 05:41:16 +08:00
|
|
|
for (arg_iterator it = Args.filtered_begin(OPT_objcxx_isystem),
|
|
|
|
ie = Args.filtered_end(); it != ie; ++it)
|
2013-01-25 09:50:47 +08:00
|
|
|
Opts.AddPath((*it)->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.
|
|
|
|
for (arg_iterator I = Args.filtered_begin(OPT_internal_isystem,
|
2011-11-07 17:17:31 +08:00
|
|
|
OPT_internal_externc_isystem),
|
2011-11-05 16:30:29 +08:00
|
|
|
E = Args.filtered_end();
|
2013-01-30 08:19:24 +08:00
|
|
|
I != E; ++I) {
|
|
|
|
frontend::IncludeDirGroup Group = frontend::System;
|
|
|
|
if ((*I)->getOption().matches(OPT_internal_externc_isystem))
|
|
|
|
Group = frontend::ExternCSystem;
|
2013-01-30 08:34:26 +08:00
|
|
|
Opts.AddPath((*I)->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.
|
|
|
|
for (arg_iterator I = Args.filtered_begin(OPT_isystem_prefix,
|
|
|
|
OPT_ino_system_prefix),
|
|
|
|
E = Args.filtered_end();
|
|
|
|
I != E; ++I)
|
2012-11-01 12:30:05 +08:00
|
|
|
Opts.AddSystemHeaderPrefix((*I)->getValue(),
|
2012-06-14 04:27:03 +08:00
|
|
|
(*I)->getOption().matches(OPT_isystem_prefix));
|
2009-12-01 11:16:53 +08:00
|
|
|
}
|
|
|
|
|
2010-12-04 09:50:27 +08:00
|
|
|
void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK,
|
|
|
|
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:
|
|
|
|
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:
|
2009-12-01 11:16:53 +08:00
|
|
|
LangStd = LangStandard::lang_gnu99;
|
|
|
|
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();
|
2012-10-18 07:07:52 +08:00
|
|
|
Opts.CPlusPlus1y = Std.isCPlusPlus1y();
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.Digraphs = Std.hasDigraphs();
|
|
|
|
Opts.GNUMode = Std.isGNUMode();
|
|
|
|
Opts.GNUInline = !Std.isC99();
|
|
|
|
Opts.HexFloats = Std.hasHexFloats();
|
|
|
|
Opts.ImplicitInt = Std.hasImplicitInt();
|
|
|
|
|
2012-06-19 06:55:02 +08:00
|
|
|
// Set OpenCL Version.
|
2009-12-01 11:16:53 +08:00
|
|
|
if (LangStd == LangStandard::lang_opencl) {
|
|
|
|
Opts.OpenCL = 1;
|
2012-06-19 06:55:02 +08:00
|
|
|
Opts.OpenCLVersion = 100;
|
|
|
|
}
|
|
|
|
else if (LangStd == LangStandard::lang_opencl11) {
|
|
|
|
Opts.OpenCL = 1;
|
|
|
|
Opts.OpenCLVersion = 110;
|
|
|
|
}
|
|
|
|
else if (LangStd == LangStandard::lang_opencl12) {
|
|
|
|
Opts.OpenCL = 1;
|
|
|
|
Opts.OpenCLVersion = 120;
|
|
|
|
}
|
|
|
|
|
|
|
|
// OpenCL has some additional defaults.
|
|
|
|
if (Opts.OpenCL) {
|
2011-09-22 02:28:29 +08:00
|
|
|
Opts.AltiVec = 0;
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.CXXOperatorNames = 1;
|
2011-09-22 02:28:29 +08:00
|
|
|
Opts.LaxVectorConversions = 0;
|
2011-02-14 09:42:53 +08:00
|
|
|
Opts.DefaultFPContract = 1;
|
2013-01-23 19:56:20 +08:00
|
|
|
Opts.NativeHalfType = 1;
|
2009-12-01 11:16:53 +08:00
|
|
|
}
|
|
|
|
|
2010-12-01 11:15:20 +08:00
|
|
|
if (LangStd == LangStandard::lang_cuda)
|
|
|
|
Opts.CUDA = 1;
|
|
|
|
|
2009-12-01 11:16:53 +08:00
|
|
|
// OpenCL and C++ both have bool, true, false keywords.
|
|
|
|
Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
// Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs
|
|
|
|
// is specified, or -std is set to a conforming mode.
|
|
|
|
Opts.Trigraphs = !Opts.GNUMode;
|
|
|
|
|
|
|
|
Opts.DollarIdents = !Opts.AsmPreprocessor;
|
2013-11-05 17:12:18 +08:00
|
|
|
|
|
|
|
// C++1y onwards has sized global deallocation functions.
|
|
|
|
Opts.SizedDeallocation = Opts.CPlusPlus1y;
|
2010-12-04 09:50:27 +08:00
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
} else if (value == "hidden") {
|
|
|
|
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,
|
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:
|
|
|
|
if (!Std.isC99())
|
|
|
|
Diags.Report(diag::err_drv_argument_not_allowed_with)
|
|
|
|
<< A->getAsString(Args) << "OpenCL";
|
|
|
|
break;
|
|
|
|
case IK_CUDA:
|
|
|
|
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)
|
|
|
|
.Default(LangStandard::lang_unspecified);
|
|
|
|
|
|
|
|
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
|
|
|
}
|
2012-06-20 07:09:52 +08:00
|
|
|
|
2010-12-04 09:50:27 +08:00
|
|
|
CompilerInvocation::setLangDefaults(Opts, IK, LangStd);
|
|
|
|
|
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
|
|
|
|
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);
|
|
|
|
|
|
|
|
// Only set ObjCARCWeak if ARC is enabled.
|
|
|
|
if (Args.hasArg(OPT_fobjc_runtime_has_weak))
|
|
|
|
Opts.ObjCARCWeak = 1;
|
|
|
|
else
|
|
|
|
Opts.ObjCARCWeak = Opts.ObjCRuntime.allowsWeak();
|
2011-06-16 07:02:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (Args.hasArg(OPT_fno_objc_infer_related_result_type))
|
|
|
|
Opts.ObjCInferRelatedResultType = 0;
|
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
|
|
|
}
|
|
|
|
|
2011-06-03 00:13:27 +08:00
|
|
|
if (Args.hasArg(OPT_fgnu89_inline))
|
|
|
|
Opts.GNUInline = 1;
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
if (Args.hasArg(OPT_trigraphs))
|
|
|
|
Opts.Trigraphs = 1;
|
|
|
|
|
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);
|
2011-10-24 23:27:23 +08:00
|
|
|
Opts.MicrosoftExt
|
|
|
|
= Args.hasArg(OPT_fms_extensions) || Args.hasArg(OPT_fms_compatibility);
|
2011-09-17 12:32:15 +08:00
|
|
|
Opts.MicrosoftMode = Args.hasArg(OPT_fms_compatibility);
|
2012-12-06 07:35:10 +08:00
|
|
|
Opts.AsmBlocks = Args.hasArg(OPT_fasm_blocks) || Opts.MicrosoftExt;
|
2013-06-15 01:17:23 +08:00
|
|
|
Opts.MSCVersion = getLastArgIntValue(Args, OPT_fmsc_version, 0, 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);
|
2011-03-19 05:23:38 +08:00
|
|
|
Opts.TraditionalCPP = Args.hasArg(OPT_traditional_cpp);
|
2011-02-23 11:16:42 +08:00
|
|
|
|
2009-12-03 02:57:08 +08:00
|
|
|
Opts.RTTI = !Args.hasArg(OPT_fno_rtti);
|
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);
|
2012-01-04 01:07:34 +08:00
|
|
|
Opts.Modules = Args.hasArg(OPT_fmodules);
|
2013-09-24 17:14:14 +08:00
|
|
|
Opts.ModulesDeclUse = Args.hasArg(OPT_fmodules_decluse);
|
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);
|
2009-12-01 11:16:53 +08:00
|
|
|
Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar);
|
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;
|
2013-07-23 08:13:01 +08:00
|
|
|
Opts.NoMathBuiltin = Args.hasArg(OPT_fno_math_builtin);
|
2009-12-17 00:59:22 +08:00
|
|
|
Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new);
|
2013-11-05 17:12:18 +08:00
|
|
|
Opts.SizedDeallocation |= Args.hasArg(OPT_fsized_deallocation);
|
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);
|
|
|
|
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);
|
|
|
|
Opts.DumpRecordLayouts = Opts.DumpRecordLayoutsSimple
|
|
|
|
|| 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-03-02 01:40:53 +08:00
|
|
|
Opts.MRTD = Args.hasArg(OPT_mrtd);
|
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);
|
2011-11-16 03:35:01 +08:00
|
|
|
Opts.CurrentModule = Args.getLastArgValue(OPT_fmodule_name);
|
2009-12-01 11:16:53 +08:00
|
|
|
|
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:
|
|
|
|
Diags.Report(diag::err_drv_invalid_value)
|
|
|
|
<< "-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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-15 14:45:29 +08:00
|
|
|
// Check if -fopenmp is specified.
|
|
|
|
Opts.OpenMP = Args.hasArg(OPT_fopenmp);
|
|
|
|
|
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
|
|
|
|
2013-04-25 02:09:54 +08:00
|
|
|
Opts.FastMath = Args.hasArg(OPT_ffast_math);
|
2012-07-19 11:52:53 +08:00
|
|
|
Opts.FiniteMathOnly = Args.hasArg(OPT_ffinite_math_only);
|
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;
|
|
|
|
case 2: Opts.setStackProtector(LangOptions::SSPReq); break;
|
2009-12-01 11:16:53 +08:00
|
|
|
}
|
2012-11-06 06:04:41 +08:00
|
|
|
|
|
|
|
// Parse -fsanitize= arguments.
|
|
|
|
std::vector<std::string> Sanitizers = Args.getAllArgValues(OPT_fsanitize_EQ);
|
|
|
|
for (unsigned I = 0, N = Sanitizers.size(); I != N; ++I) {
|
|
|
|
// Since the Opts.Sanitize* values are bitfields, it's a little tricky to
|
|
|
|
// efficiently map string values to them. Perform the mapping indirectly:
|
|
|
|
// convert strings to enumerated values, then switch over the enum to set
|
|
|
|
// the right bitfield value.
|
|
|
|
enum Sanitizer {
|
|
|
|
#define SANITIZER(NAME, ID) \
|
|
|
|
ID,
|
|
|
|
#include "clang/Basic/Sanitizers.def"
|
|
|
|
Unknown
|
|
|
|
};
|
|
|
|
switch (llvm::StringSwitch<unsigned>(Sanitizers[I])
|
|
|
|
#define SANITIZER(NAME, ID) \
|
|
|
|
.Case(NAME, ID)
|
|
|
|
#include "clang/Basic/Sanitizers.def"
|
|
|
|
.Default(Unknown)) {
|
|
|
|
#define SANITIZER(NAME, ID) \
|
|
|
|
case ID: \
|
2013-01-18 19:30:38 +08:00
|
|
|
Opts.Sanitize.ID = true; \
|
2012-11-06 06:04:41 +08:00
|
|
|
break;
|
|
|
|
#include "clang/Basic/Sanitizers.def"
|
|
|
|
|
|
|
|
case Unknown:
|
|
|
|
Diags.Report(diag::err_drv_invalid_value)
|
|
|
|
<< "-fsanitize=" << Sanitizers[I];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
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);
|
2010-10-15 04:14:25 +08:00
|
|
|
for (arg_iterator it = Args.filtered_begin(OPT_error_on_deserialized_pch_decl),
|
|
|
|
ie = Args.filtered_end(); it != ie; ++it) {
|
|
|
|
const Arg *A = *it;
|
2012-11-01 12:30:05 +08:00
|
|
|
Opts.DeserializedPCHDeclsToErrorOn.insert(A->getValue());
|
2010-10-15 04:14:25 +08:00
|
|
|
}
|
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.
|
|
|
|
for (arg_iterator it = Args.filtered_begin(OPT_D, OPT_U),
|
|
|
|
ie = Args.filtered_end(); it != ie; ++it) {
|
2010-06-12 06:00:13 +08:00
|
|
|
if ((*it)->getOption().matches(OPT_D))
|
2012-11-01 12:30:05 +08:00
|
|
|
Opts.addMacroDef((*it)->getValue());
|
2009-12-01 11:16:53 +08:00
|
|
|
else
|
2012-11-01 12:30:05 +08:00
|
|
|
Opts.addMacroUndef((*it)->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.
|
2013-02-06 00:36:52 +08:00
|
|
|
for (arg_iterator it = Args.filtered_begin(OPT_include),
|
2009-12-01 11:16:53 +08:00
|
|
|
ie = Args.filtered_end(); it != ie; ++it) {
|
2010-06-12 06:00:13 +08:00
|
|
|
const Arg *A = *it;
|
2012-11-01 12:30:05 +08:00
|
|
|
Opts.Includes.push_back(A->getValue());
|
2009-12-01 11:16:53 +08:00
|
|
|
}
|
2009-12-03 13:11:16 +08:00
|
|
|
|
2011-03-10 01:21:42 +08:00
|
|
|
for (arg_iterator it = Args.filtered_begin(OPT_chain_include),
|
|
|
|
ie = Args.filtered_end(); it != ie; ++it) {
|
|
|
|
const Arg *A = *it;
|
2012-11-01 12:30:05 +08:00
|
|
|
Opts.ChainedIncludes.push_back(A->getValue());
|
2011-03-10 01:21:42 +08:00
|
|
|
}
|
|
|
|
|
2010-04-14 11:54:58 +08:00
|
|
|
// Include 'altivec.h' if -faltivec option present
|
|
|
|
if (Args.hasArg(OPT_faltivec))
|
|
|
|
Opts.Includes.push_back("altivec.h");
|
|
|
|
|
2009-12-03 13:11:16 +08:00
|
|
|
for (arg_iterator it = Args.filtered_begin(OPT_remap_file),
|
|
|
|
ie = Args.filtered_end(); it != ie; ++it) {
|
2010-06-12 06:00:13 +08:00
|
|
|
const Arg *A = *it;
|
2011-07-23 18:55:15 +08:00
|
|
|
std::pair<StringRef,StringRef> Split =
|
2012-11-01 12:30:05 +08:00
|
|
|
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);
|
|
|
|
}
|
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:
|
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);
|
2009-12-01 11:16:53 +08:00
|
|
|
}
|
|
|
|
|
2013-03-06 10:08:54 +08:00
|
|
|
static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args) {
|
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);
|
2010-06-11 09:06:47 +08:00
|
|
|
Opts.CXXABI = Args.getLastArgValue(OPT_cxx_abi);
|
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));
|
2009-12-01 11:16:53 +08:00
|
|
|
|
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();
|
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.
|
2012-05-01 22:57:16 +08:00
|
|
|
OwningPtr<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;
|
2012-02-05 10:12:40 +08:00
|
|
|
OwningPtr<InputArgList> Args(
|
2013-08-03 04:16:22 +08:00
|
|
|
Opts->ParseArgs(ArgBegin, ArgEnd, MissingArgIndex, MissingArgCount,
|
|
|
|
IncludedFlagsBitmask));
|
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)
|
|
|
|
<< 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.
|
|
|
|
for (arg_iterator it = Args->filtered_begin(OPT_UNKNOWN),
|
2011-12-23 11:05:38 +08:00
|
|
|
ie = Args->filtered_end(); it != ie; ++it) {
|
2010-06-12 06:00:13 +08:00
|
|
|
Diags.Report(diag::err_drv_unknown_argument) << (*it)->getAsString(*Args);
|
2011-12-23 11:05:38 +08:00
|
|
|
Success = false;
|
|
|
|
}
|
2009-12-01 11:16:53 +08:00
|
|
|
|
2012-08-31 12:36:05 +08:00
|
|
|
Success = ParseAnalyzerArgs(*Res.getAnalyzerOpts(), *Args, Diags) && Success;
|
2012-01-25 08:20:29 +08:00
|
|
|
Success = ParseMigratorArgs(Res.getMigratorOpts(), *Args) && Success;
|
2009-12-01 11:16:53 +08:00
|
|
|
ParseDependencyOutputArgs(Res.getDependencyOutputOpts(), *Args);
|
2012-03-14 04:09:56 +08:00
|
|
|
Success = ParseDiagnosticArgs(Res.getDiagnosticOpts(), *Args, &Diags)
|
2011-12-23 11:05:38 +08:00
|
|
|
&& Success;
|
2013-02-22 22:21:27 +08:00
|
|
|
ParseCommentArgs(Res.getLangOpts()->CommentOpts, *Args);
|
2010-11-04 06:45:23 +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
|
2010-06-08 07:22:09 +08:00
|
|
|
InputKind DashX = ParseFrontendArgs(Res.getFrontendOpts(), *Args, Diags);
|
2014-01-07 09:19:08 +08:00
|
|
|
ParseTargetArgs(Res.getTargetOpts(), *Args);
|
|
|
|
Success = ParseCodeGenArgs(Res.getCodeGenOpts(), *Args, DashX, Diags,
|
|
|
|
Res.getTargetOpts()) && Success;
|
2009-12-13 11:45:58 +08:00
|
|
|
ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), *Args);
|
2011-02-26 01:24:55 +08:00
|
|
|
if (DashX != IK_AST && DashX != IK_LLVM_IR) {
|
2011-11-18 07:01:24 +08:00
|
|
|
ParseLangArgs(*Res.getLangOpts(), *Args, DashX, Diags);
|
2011-02-26 01:24:55 +08:00
|
|
|
if (Res.getFrontendOpts().ProgramAction == frontend::RewriteObjC)
|
2011-11-18 07:01:24 +08:00
|
|
|
Res.getLangOpts()->ObjCExceptions = 1;
|
2011-02-26 01:24:55 +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
|
2010-11-23 16:35:12 +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());
|
2010-11-23 16:35:12 +08:00
|
|
|
ParsePreprocessorArgs(Res.getPreprocessorOpts(), *Args, FileMgr, Diags);
|
2013-01-30 09:52:57 +08:00
|
|
|
ParsePreprocessorOutputArgs(Res.getPreprocessorOutputOpts(), *Args,
|
|
|
|
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;
|
|
|
|
|
|
|
|
public:
|
|
|
|
ModuleSignature() : CurBit(0), CurValue(0) { }
|
|
|
|
|
|
|
|
void add(uint64_t Value, unsigned Bits);
|
|
|
|
void add(StringRef Value);
|
|
|
|
void flush();
|
|
|
|
|
|
|
|
llvm::APInt getAsInteger() const;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
void ModuleSignature::add(uint64_t Value, unsigned int NumBits) {
|
|
|
|
CurValue |= Value << CurBit;
|
|
|
|
if (CurBit + NumBits < 64) {
|
|
|
|
CurBit += NumBits;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add the current word.
|
|
|
|
Data.push_back(CurValue);
|
|
|
|
|
|
|
|
if (CurBit)
|
|
|
|
CurValue = Value >> (64-CurBit);
|
|
|
|
else
|
|
|
|
CurValue = 0;
|
|
|
|
CurBit = (CurBit+NumBits) & 63;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ModuleSignature::flush() {
|
|
|
|
if (CurBit == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
Data.push_back(CurValue);
|
|
|
|
CurBit = 0;
|
|
|
|
CurValue = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ModuleSignature::add(StringRef Value) {
|
|
|
|
for (StringRef::iterator I = Value.begin(), IEnd = Value.end(); I != IEnd;++I)
|
|
|
|
add(*I, 8);
|
|
|
|
}
|
|
|
|
|
|
|
|
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"
|
|
|
|
|
2012-11-06 03:45:09 +08:00
|
|
|
// Extend the signature with the target options.
|
|
|
|
code = hash_combine(code, TargetOpts->Triple, TargetOpts->CPU,
|
|
|
|
TargetOpts->ABI, TargetOpts->CXXABI,
|
|
|
|
TargetOpts->LinkerVersion);
|
|
|
|
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);
|
|
|
|
|
2011-10-17 22:55:37 +08:00
|
|
|
for (std::vector<std::pair<std::string, bool/*isUndef*/> >::const_iterator
|
|
|
|
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
|
|
|
|
|
|
|
// Extend the signature with the sysroot.
|
|
|
|
code = hash_combine(code, hsOpts.Sysroot, hsOpts.UseBuiltinIncludes,
|
|
|
|
hsOpts.UseStandardSystemIncludes,
|
|
|
|
hsOpts.UseStandardCXXIncludes,
|
|
|
|
hsOpts.UseLibcxx);
|
|
|
|
|
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()) {
|
|
|
|
llvm::OwningPtr<llvm::MemoryBuffer> buffer;
|
|
|
|
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");
|
2013-11-08 08:38:03 +08:00
|
|
|
if (!llvm::MemoryBuffer::getFile(systemVersionFile.str(), 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 {
|
|
|
|
|
|
|
|
// Declared in clang/Frontend/Utils.h.
|
|
|
|
int getLastArgIntValue(const ArgList &Args, OptSpecifier Id, int Default,
|
|
|
|
DiagnosticsEngine *Diags) {
|
|
|
|
int Res = Default;
|
|
|
|
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
|
|
|
|
|
|
|
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];
|
2013-12-27 16:11:08 +08:00
|
|
|
static llvm::sys::cas_flag GraveYardSize;
|
|
|
|
llvm::sys::cas_flag Idx = llvm::sys::AtomicIncrement(&GraveYardSize) - 1;
|
|
|
|
if (Idx >= kGraveYardMaxSize)
|
|
|
|
return;
|
|
|
|
GraveYard[Idx] = Ptr;
|
|
|
|
}
|
2013-06-15 01:17:23 +08:00
|
|
|
}
|