summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSaleem Abdulrasool <compnerd@compnerd.org>2014-05-08 02:28:32 +0000
committerSaleem Abdulrasool <compnerd@compnerd.org>2014-05-08 02:28:32 +0000
commit62849c677c06828f80fd2a5691b2569983785101 (patch)
tree72db51e51f2c67bc3d843eb2a57bc89d354912ee
parent2ff4948035352c6c78cefec1da1c317bcffd3a21 (diff)
downloadbcm5719-llvm-62849c677c06828f80fd2a5691b2569983785101.tar.gz
bcm5719-llvm-62849c677c06828f80fd2a5691b2569983785101.zip
Driver: parse -mcmodel earlier
This addresses an existing FIXME item in the driver. The code model flag was parsed in the actual tool rather than in the driver. This was problematic since the value may be invalid. In that case, we would silently treat it as a default value in non-assert builds, and abort in assert builds. Add a check in the driver to validate that the value being passed is valid, and if not provide a proper error message. llvm-svn: 208275
-rw-r--r--clang/lib/CodeGen/BackendUtil.cpp25
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp14
-rw-r--r--clang/test/Driver/code-model.c13
3 files changed, 37 insertions, 15 deletions
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 8d4f69afc35..85d8b645731 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -14,6 +14,7 @@
#include "clang/Frontend/CodeGenOptions.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/Utils.h"
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/Bitcode/BitcodeWriterPass.h"
#include "llvm/CodeGen/RegAllocRegistry.h"
#include "llvm/CodeGen/SchedulerRegistry.h"
@@ -378,20 +379,16 @@ TargetMachine *EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) {
TargetMachine::setFunctionSections(CodeGenOpts.FunctionSections);
TargetMachine::setDataSections (CodeGenOpts.DataSections);
- // FIXME: Parse this earlier.
- llvm::CodeModel::Model CM;
- if (CodeGenOpts.CodeModel == "small") {
- CM = llvm::CodeModel::Small;
- } else if (CodeGenOpts.CodeModel == "kernel") {
- CM = llvm::CodeModel::Kernel;
- } else if (CodeGenOpts.CodeModel == "medium") {
- CM = llvm::CodeModel::Medium;
- } else if (CodeGenOpts.CodeModel == "large") {
- CM = llvm::CodeModel::Large;
- } else {
- assert(CodeGenOpts.CodeModel.empty() && "Invalid code model!");
- CM = llvm::CodeModel::Default;
- }
+ unsigned CodeModel =
+ llvm::StringSwitch<unsigned>(CodeGenOpts.CodeModel)
+ .Case("small", llvm::CodeModel::Small)
+ .Case("kernel", llvm::CodeModel::Kernel)
+ .Case("medium", llvm::CodeModel::Medium)
+ .Case("large", llvm::CodeModel::Medium)
+ .Case("default", llvm::CodeModel::Default)
+ .Default(~0u);
+ assert(CodeModel != ~0u && "invalid code model!");
+ llvm::CodeModel::Model CM = static_cast<llvm::CodeModel::Model>(CodeModel);
SmallVector<const char *, 16> BackendArgs;
BackendArgs.push_back("clang"); // Fake program name.
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 0b6b765dba7..a6b1b458e79 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -27,6 +27,7 @@
#include "llvm/Option/ArgList.h"
#include "llvm/Option/OptTable.h"
#include "llvm/Option/Option.h"
+#include "llvm/Support/CodeGen.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Host.h"
@@ -295,6 +296,17 @@ static void ParseCommentArgs(CommentOptions &Opts, ArgList &Args) {
Opts.ParseAllComments = Args.hasArg(OPT_fparse_all_comments);
}
+static StringRef getCodeModel(ArgList &Args, DiagnosticsEngine &Diags) {
+ if (Arg *A = Args.getLastArg(OPT_mcode_model)) {
+ StringRef Value = A->getValue();
+ if (Value == "small" || Value == "kernel" || Value == "medium" ||
+ Value == "large")
+ return Value;
+ Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Value;
+ }
+ return "default";
+}
+
static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
DiagnosticsEngine &Diags,
const TargetOptions &TargetOpts) {
@@ -376,7 +388,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Opts.CUDAIsDevice = Args.hasArg(OPT_fcuda_is_device);
Opts.CXAAtExit = !Args.hasArg(OPT_fno_use_cxa_atexit);
Opts.CXXCtorDtorAliases = Args.hasArg(OPT_mconstructor_aliases);
- Opts.CodeModel = Args.getLastArgValue(OPT_mcode_model);
+ Opts.CodeModel = getCodeModel(Args, Diags);
Opts.DebugPass = Args.getLastArgValue(OPT_mdebug_pass);
Opts.DisableFPElim = Args.hasArg(OPT_mdisable_fp_elim);
Opts.DisableFree = Args.hasArg(OPT_disable_free);
diff --git a/clang/test/Driver/code-model.c b/clang/test/Driver/code-model.c
new file mode 100644
index 00000000000..001ca606cde
--- /dev/null
+++ b/clang/test/Driver/code-model.c
@@ -0,0 +1,13 @@
+// RUN: %clang -### -c -mcmodel=small %s 2>&1 | FileCheck -check-prefix CHECK-SMALL %s
+// RUN: %clang -### -S -mcmodel=kernel %s 2>&1 | FileCheck -check-prefix CHECK-KERNEL %s
+// RUN: %clang -### -c -mcmodel=medium %s 2>&1 | FileCheck -check-prefix CHECK-MEDIUM %s
+// RUN: %clang -### -S -mcmodel=large %s 2>&1 | FileCheck -check-prefix CHECK-LARGE %s
+// RUN: not %clang -c -mcmodel=lager %s 2>&1 | FileCheck -check-prefix CHECK-INVALID %s
+
+// CHECK-SMALL: "-mcode-model" "small"
+// CHECK-KERNEL: "-mcode-model" "kernel"
+// CHECK-MEDIUM: "-mcode-model" "medium"
+// CHECK-LARGE: "-mcode-model" "large"
+
+// CHECK-INVALID: error: invalid value 'lager' in '-mcode-model lager'
+
OpenPOWER on IntegriCloud