aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Frontend/CompilerInvocation.h4
-rw-r--r--lib/Frontend/CompilerInvocation.cpp90
-rw-r--r--lib/Frontend/CreateInvocationFromCommandLine.cpp9
-rw-r--r--tools/arcmt-test/arcmt-test.cpp8
-rw-r--r--tools/driver/cc1_main.cpp17
-rw-r--r--tools/driver/cc1as_main.cpp28
6 files changed, 104 insertions, 52 deletions
diff --git a/include/clang/Frontend/CompilerInvocation.h b/include/clang/Frontend/CompilerInvocation.h
index bbefdb662d..821336c32c 100644
--- a/include/clang/Frontend/CompilerInvocation.h
+++ b/include/clang/Frontend/CompilerInvocation.h
@@ -90,13 +90,13 @@ public:
/// @{
/// CreateFromArgs - Create a compiler invocation from a list of input
- /// options.
+ /// options. Returns true on success.
///
/// \param Res [out] - The resulting invocation.
/// \param ArgBegin - The first element in the argument vector.
/// \param ArgEnd - The last element in the argument vector.
/// \param Diags - The diagnostic engine to use for errors.
- static void CreateFromArgs(CompilerInvocation &Res,
+ static bool CreateFromArgs(CompilerInvocation &Res,
const char* const *ArgBegin,
const char* const *ArgEnd,
DiagnosticsEngine &Diags);
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 3ad555bfe8..18b247c9b9 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -944,10 +944,10 @@ static unsigned getOptimizationLevel(ArgList &Args, InputKind IK,
Args.getLastArgIntValue(OPT_O, DefaultOpt, Diags);
}
-static void ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
+static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
DiagnosticsEngine &Diags) {
using namespace cc1options;
-
+ bool Success = true;
if (Arg *A = Args.getLastArg(OPT_analyzer_store)) {
StringRef Name = A->getValue(Args);
AnalysisStores Value = llvm::StringSwitch<AnalysisStores>(Name)
@@ -955,12 +955,13 @@ static void ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
.Case(CMDFLAG, NAME##Model)
#include "clang/Frontend/Analyses.def"
.Default(NumStores);
- // FIXME: Error handling.
- if (Value == NumStores)
+ if (Value == NumStores) {
Diags.Report(diag::err_drv_invalid_value)
<< A->getAsString(Args) << Name;
- else
+ Success = false;
+ } else {
Opts.AnalysisStoreOpt = Value;
+ }
}
if (Arg *A = Args.getLastArg(OPT_analyzer_constraints)) {
@@ -970,12 +971,13 @@ static void ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
.Case(CMDFLAG, NAME##Model)
#include "clang/Frontend/Analyses.def"
.Default(NumConstraints);
- // FIXME: Error handling.
- if (Value == NumConstraints)
+ if (Value == NumConstraints) {
Diags.Report(diag::err_drv_invalid_value)
<< A->getAsString(Args) << Name;
- else
+ Success = false;
+ } else {
Opts.AnalysisConstraintsOpt = Value;
+ }
}
if (Arg *A = Args.getLastArg(OPT_analyzer_output)) {
@@ -985,12 +987,13 @@ static void ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
.Case(CMDFLAG, PD_##NAME)
#include "clang/Frontend/Analyses.def"
.Default(NUM_ANALYSIS_DIAG_CLIENTS);
- // FIXME: Error handling.
- if (Value == NUM_ANALYSIS_DIAG_CLIENTS)
+ if (Value == NUM_ANALYSIS_DIAG_CLIENTS) {
Diags.Report(diag::err_drv_invalid_value)
<< A->getAsString(Args) << Name;
- else
+ Success = false;
+ } else {
Opts.AnalysisDiagOpt = Value;
+ }
}
if (Arg *A = Args.getLastArg(OPT_analyzer_purge)) {
@@ -1000,12 +1003,13 @@ static void ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
.Case(CMDFLAG, NAME)
#include "clang/Frontend/Analyses.def"
.Default(NumPurgeModes);
- // FIXME: Error handling.
- if (Value == NumPurgeModes)
+ if (Value == NumPurgeModes) {
Diags.Report(diag::err_drv_invalid_value)
<< A->getAsString(Args) << Name;
- else
+ Success = false;
+ } else {
Opts.AnalysisPurgeOpt = Value;
+ }
}
Opts.ShowCheckerHelp = Args.hasArg(OPT_analyzer_checker_help);
@@ -1041,17 +1045,21 @@ static void ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
for (unsigned i = 0, e = checkers.size(); i != e; ++i)
Opts.CheckersControlList.push_back(std::make_pair(checkers[i], enable));
}
+
+ return Success;
}
-static void ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
+static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
DiagnosticsEngine &Diags) {
using namespace cc1options;
+ bool Success = true;
Opts.OptimizationLevel = getOptimizationLevel(Args, IK, Diags);
if (Opts.OptimizationLevel > 3) {
Diags.Report(diag::err_drv_invalid_value)
<< Args.getLastArg(OPT_O)->getAsString(Args) << Opts.OptimizationLevel;
Opts.OptimizationLevel = 3;
+ Success = false;
}
// We must always run at least the always inlining pass.
@@ -1140,11 +1148,15 @@ static void ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
.Case("non-legacy", CodeGenOptions::NonLegacy)
.Case("mixed", CodeGenOptions::Mixed)
.Default(~0U);
- if (Method == ~0U)
+ if (Method == ~0U) {
Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name;
- else
+ Success = false;
+ } else {
Opts.ObjCDispatchMethod = Method;
+ }
}
+
+ return Success;
}
static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts,
@@ -1159,9 +1171,11 @@ static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts,
Opts.AddMissingHeaderDeps = Args.hasArg(OPT_MG);
}
-static void ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
+static bool ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
DiagnosticsEngine &Diags) {
using namespace cc1options;
+ bool Success = true;
+
Opts.DiagnosticLogFile = Args.getLastArgValue(OPT_diagnostic_log_file);
Opts.DiagnosticSerializationFile =
Args.getLastArgValue(OPT_diagnostic_serialized_file);
@@ -1192,10 +1206,12 @@ static void ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
Opts.ShowOverloads = DiagnosticsEngine::Ovl_Best;
else if (ShowOverloads == "all")
Opts.ShowOverloads = DiagnosticsEngine::Ovl_All;
- else
+ else {
Diags.Report(diag::err_drv_invalid_value)
<< Args.getLastArg(OPT_fshow_overloads_EQ)->getAsString(Args)
<< ShowOverloads;
+ Success = false;
+ }
StringRef ShowCategory =
Args.getLastArgValue(OPT_fdiagnostics_show_category, "none");
@@ -1205,23 +1221,27 @@ static void ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
Opts.ShowCategories = 1;
else if (ShowCategory == "name")
Opts.ShowCategories = 2;
- else
+ else {
Diags.Report(diag::err_drv_invalid_value)
<< Args.getLastArg(OPT_fdiagnostics_show_category)->getAsString(Args)
<< ShowCategory;
+ Success = false;
+ }
StringRef Format =
Args.getLastArgValue(OPT_fdiagnostics_format, "clang");
if (Format == "clang")
Opts.Format = DiagnosticOptions::Clang;
- else if (Format == "msvc")
+ else if (Format == "msvc")
Opts.Format = DiagnosticOptions::Msvc;
- else if (Format == "vi")
+ else if (Format == "vi")
Opts.Format = DiagnosticOptions::Vi;
- else
+ else {
Diags.Report(diag::err_drv_invalid_value)
<< Args.getLastArg(OPT_fdiagnostics_format)->getAsString(Args)
<< Format;
+ Success = false;
+ }
Opts.ShowSourceRanges = Args.hasArg(OPT_fdiagnostics_print_source_range_info);
Opts.ShowParseableFixits = Args.hasArg(OPT_fdiagnostics_parseable_fixits);
@@ -1248,6 +1268,8 @@ static void ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
Opts.MessageLength = Args.getLastArgIntValue(OPT_fmessage_length, 0, Diags);
Opts.DumpBuildInformation = Args.getLastArgValue(OPT_dump_build_information);
Opts.Warnings = Args.getAllArgValues(OPT_W);
+
+ return Success;
}
static void ParseFileSystemArgs(FileSystemOptions &Opts, ArgList &Args) {
@@ -1994,10 +2016,12 @@ static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args) {
//
-void CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,
+bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,
const char *const *ArgBegin,
const char *const *ArgEnd,
DiagnosticsEngine &Diags) {
+ bool Success = true;
+
// Parse the arguments.
llvm::OwningPtr<OptTable> Opts(createCC1OptTable());
unsigned MissingArgIndex, MissingArgCount;
@@ -2005,22 +2029,28 @@ void CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,
Opts->ParseArgs(ArgBegin, ArgEnd,MissingArgIndex, MissingArgCount));
// Check for missing argument error.
- if (MissingArgCount)
+ if (MissingArgCount) {
Diags.Report(diag::err_drv_missing_argument)
<< Args->getArgString(MissingArgIndex) << MissingArgCount;
+ Success = false;
+ }
// Issue errors on unknown arguments.
for (arg_iterator it = Args->filtered_begin(OPT_UNKNOWN),
- ie = Args->filtered_end(); it != ie; ++it)
+ ie = Args->filtered_end(); it != ie; ++it) {
Diags.Report(diag::err_drv_unknown_argument) << (*it)->getAsString(*Args);
+ Success = false;
+ }
- ParseAnalyzerArgs(Res.getAnalyzerOpts(), *Args, Diags);
+ Success = ParseAnalyzerArgs(Res.getAnalyzerOpts(), *Args, Diags) && Success;
ParseDependencyOutputArgs(Res.getDependencyOutputOpts(), *Args);
- ParseDiagnosticArgs(Res.getDiagnosticOpts(), *Args, Diags);
+ Success = ParseDiagnosticArgs(Res.getDiagnosticOpts(), *Args, Diags)
+ && Success;
ParseFileSystemArgs(Res.getFileSystemOpts(), *Args);
// FIXME: We shouldn't have to pass the DashX option around here
InputKind DashX = ParseFrontendArgs(Res.getFrontendOpts(), *Args, Diags);
- ParseCodeGenArgs(Res.getCodeGenOpts(), *Args, DashX, Diags);
+ Success = ParseCodeGenArgs(Res.getCodeGenOpts(), *Args, DashX, Diags)
+ && Success;
ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), *Args);
if (DashX != IK_AST && DashX != IK_LLVM_IR) {
ParseLangArgs(*Res.getLangOpts(), *Args, DashX, Diags);
@@ -2035,6 +2065,8 @@ void CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,
ParsePreprocessorArgs(Res.getPreprocessorOpts(), *Args, FileMgr, Diags);
ParsePreprocessorOutputArgs(Res.getPreprocessorOutputOpts(), *Args);
ParseTargetArgs(Res.getTargetOpts(), *Args);
+
+ return Success;
}
namespace {
diff --git a/lib/Frontend/CreateInvocationFromCommandLine.cpp b/lib/Frontend/CreateInvocationFromCommandLine.cpp
index e94b944f04..f7a296143f 100644
--- a/lib/Frontend/CreateInvocationFromCommandLine.cpp
+++ b/lib/Frontend/CreateInvocationFromCommandLine.cpp
@@ -80,11 +80,12 @@ clang::createInvocationFromCommandLine(ArrayRef<const char *> ArgList,
}
const driver::ArgStringList &CCArgs = Cmd->getArguments();
- CompilerInvocation *CI = new CompilerInvocation();
- CompilerInvocation::CreateFromArgs(*CI,
+ llvm::OwningPtr<CompilerInvocation> CI(new CompilerInvocation());
+ if (!CompilerInvocation::CreateFromArgs(*CI,
const_cast<const char **>(CCArgs.data()),
const_cast<const char **>(CCArgs.data()) +
CCArgs.size(),
- *Diags);
- return CI;
+ *Diags))
+ return 0;
+ return CI.take();
}
diff --git a/tools/arcmt-test/arcmt-test.cpp b/tools/arcmt-test/arcmt-test.cpp
index 3f91fcf124..3dc4c11667 100644
--- a/tools/arcmt-test/arcmt-test.cpp
+++ b/tools/arcmt-test/arcmt-test.cpp
@@ -118,7 +118,8 @@ static bool checkForMigration(StringRef resourcesPath,
}
CompilerInvocation CI;
- CompilerInvocation::CreateFromArgs(CI, Args.begin(), Args.end(), *Diags);
+ if (!CompilerInvocation::CreateFromArgs(CI, Args.begin(), Args.end(), *Diags))
+ return true;
if (CI.getFrontendOpts().Inputs.empty()) {
llvm::errs() << "error: no input files\n";
@@ -159,8 +160,9 @@ static bool performTransformations(StringRef resourcesPath,
new DiagnosticsEngine(DiagID, DiagClient));
CompilerInvocation origCI;
- CompilerInvocation::CreateFromArgs(origCI, Args.begin(), Args.end(),
- *TopDiags);
+ if (!CompilerInvocation::CreateFromArgs(origCI, Args.begin(), Args.end(),
+ *TopDiags))
+ return true;
if (origCI.getFrontendOpts().Inputs.empty()) {
llvm::errs() << "error: no input files\n";
diff --git a/tools/driver/cc1_main.cpp b/tools/driver/cc1_main.cpp
index f1fb68d539..0a14fdd315 100644
--- a/tools/driver/cc1_main.cpp
+++ b/tools/driver/cc1_main.cpp
@@ -77,7 +77,8 @@ static int cc1_test(DiagnosticsEngine &Diags,
// Create a compiler invocation.
llvm::errs() << "cc1 creating invocation.\n";
CompilerInvocation Invocation;
- CompilerInvocation::CreateFromArgs(Invocation, ArgBegin, ArgEnd, Diags);
+ if (!CompilerInvocation::CreateFromArgs(Invocation, ArgBegin, ArgEnd, Diags))
+ return 1;
// Convert the invocation back to argument strings.
std::vector<std::string> InvocationArgs;
@@ -95,8 +96,9 @@ static int cc1_test(DiagnosticsEngine &Diags,
// Convert those arguments to another invocation, and check that we got the
// same thing.
CompilerInvocation Invocation2;
- CompilerInvocation::CreateFromArgs(Invocation2, Invocation2Args.begin(),
- Invocation2Args.end(), Diags);
+ if (!CompilerInvocation::CreateFromArgs(Invocation2, Invocation2Args.begin(),
+ Invocation2Args.end(), Diags))
+ return 1;
// FIXME: Implement CompilerInvocation comparison.
if (true) {
@@ -135,8 +137,11 @@ int cc1_main(const char **ArgBegin, const char **ArgEnd,
// well formed diagnostic object.
TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer;
DiagnosticsEngine Diags(DiagID, DiagsBuffer);
- CompilerInvocation::CreateFromArgs(Clang->getInvocation(), ArgBegin, ArgEnd,
- Diags);
+ bool Success;
+ Success = CompilerInvocation::CreateFromArgs(Clang->getInvocation(),
+ ArgBegin, ArgEnd, Diags);
+ if (!Success)
+ return 1;
// Infer the builtin include path if unspecified.
if (Clang->getHeaderSearchOpts().UseBuiltinIncludes &&
@@ -157,7 +162,7 @@ int cc1_main(const char **ArgBegin, const char **ArgEnd,
DiagsBuffer->FlushDiagnostics(Clang->getDiagnostics());
// Execute the frontend actions.
- bool Success = ExecuteCompilerInvocation(Clang.get());
+ Success = ExecuteCompilerInvocation(Clang.get());
// If any timers were active but haven't been destroyed yet, print their
// results now. This happens in -disable-free mode.
diff --git a/tools/driver/cc1as_main.cpp b/tools/driver/cc1as_main.cpp
index 9959b0d296..4591a36873 100644
--- a/tools/driver/cc1as_main.cpp
+++ b/tools/driver/cc1as_main.cpp
@@ -122,17 +122,19 @@ public:
NoExecStack = 0;
}
- static void CreateFromArgs(AssemblerInvocation &Res, const char **ArgBegin,
+ static bool CreateFromArgs(AssemblerInvocation &Res, const char **ArgBegin,
const char **ArgEnd, DiagnosticsEngine &Diags);
};
}
-void AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
+bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
const char **ArgBegin,
const char **ArgEnd,
DiagnosticsEngine &Diags) {
using namespace clang::driver::cc1asoptions;
+ bool Success = true;
+
// Parse the arguments.
OwningPtr<OptTable> OptTbl(createCC1AsOptTable());
unsigned MissingArgIndex, MissingArgCount;
@@ -140,14 +142,18 @@ void AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
OptTbl->ParseArgs(ArgBegin, ArgEnd,MissingArgIndex, MissingArgCount));
// Check for missing argument error.
- if (MissingArgCount)
+ if (MissingArgCount) {
Diags.Report(diag::err_drv_missing_argument)
<< Args->getArgString(MissingArgIndex) << MissingArgCount;
+ Success = false;
+ }
// Issue errors on unknown arguments.
for (arg_iterator it = Args->filtered_begin(cc1asoptions::OPT_UNKNOWN),
- ie = Args->filtered_end(); it != ie; ++it)
+ ie = Args->filtered_end(); it != ie; ++it) {
Diags.Report(diag::err_drv_unknown_argument) << (*it) ->getAsString(*Args);
+ Success = false;
+ }
// Construct the invocation.
@@ -171,8 +177,10 @@ void AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
const Arg *A = it;
if (First)
Opts.InputFile = A->getValue(*Args);
- else
+ else {
Diags.Report(diag::err_drv_unknown_argument) << A->getAsString(*Args);
+ Success = false;
+ }
}
}
Opts.LLVMArgs = Args->getAllArgValues(OPT_mllvm);
@@ -186,10 +194,11 @@ void AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
.Case("null", FT_Null)
.Case("obj", FT_Obj)
.Default(~0U);
- if (OutputType == ~0U)
+ if (OutputType == ~0U) {
Diags.Report(diag::err_drv_invalid_value)
<< A->getAsString(*Args) << Name;
- else
+ Success = false;
+ } else
Opts.OutputType = FileType(OutputType);
}
Opts.ShowHelp = Args->hasArg(OPT_help);
@@ -204,6 +213,8 @@ void AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
// Assemble Options
Opts.RelaxAll = Args->hasArg(OPT_relax_all);
Opts.NoExecStack = Args->hasArg(OPT_no_exec_stack);
+
+ return true;
}
static formatted_raw_ostream *GetOutputStream(AssemblerInvocation &Opts,
@@ -374,7 +385,8 @@ int cc1as_main(const char **ArgBegin, const char **ArgEnd,
// Parse the arguments.
AssemblerInvocation Asm;
- AssemblerInvocation::CreateFromArgs(Asm, ArgBegin, ArgEnd, Diags);
+ if (!AssemblerInvocation::CreateFromArgs(Asm, ArgBegin, ArgEnd, Diags))
+ return 1;
// Honor -help.
if (Asm.ShowHelp) {