forked from OSchip/llvm-project
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
This commit is contained in:
parent
2ff4948035
commit
62849c677c
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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'
|
||||
|
Loading…
Reference in New Issue