summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Driver/MSVCToolChain.cpp98
-rw-r--r--clang/lib/Driver/ToolChains.h4
-rw-r--r--clang/lib/Driver/Tools.cpp22
3 files changed, 120 insertions, 4 deletions
diff --git a/clang/lib/Driver/MSVCToolChain.cpp b/clang/lib/Driver/MSVCToolChain.cpp
index c816b29dca2..b890375742e 100644
--- a/clang/lib/Driver/MSVCToolChain.cpp
+++ b/clang/lib/Driver/MSVCToolChain.cpp
@@ -528,3 +528,101 @@ SanitizerMask MSVCToolChain::getSupportedSanitizers() const {
Res |= SanitizerKind::Address;
return Res;
}
+
+llvm::opt::DerivedArgList *
+MSVCToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
+ const char *BoundArch) const {
+ DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
+ const OptTable &Opts = getDriver().getOpts();
+
+ // The -O[12xd] flag actually expands to several flags. We must desugar the
+ // flags so that options embedded can be negated. For example, the '-O2' flag
+ // enables '-Oy'. Expanding '-O2' into its constituent flags allows us to
+ // correctly handle '-O2 -Oy-' where the trailing '-Oy-' disables a single
+ // aspect of '-O2'.
+ //
+ // Note that this expansion logic only applies to the *last* of '[12xd]'.
+
+ // First step is to search for the character we'd like to expand.
+ const char *ExpandChar = nullptr;
+ for (Arg *A : Args) {
+ if (!A->getOption().matches(options::OPT__SLASH_O))
+ continue;
+ StringRef OptStr = A->getValue();
+ for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
+ const char &OptChar = *(OptStr.data() + I);
+ if (OptChar == '1' || OptChar == '2' || OptChar == 'x' || OptChar == 'd')
+ ExpandChar = OptStr.data() + I;
+ }
+ }
+
+ // The -O flag actually takes an amalgam of other options. For example,
+ // '/Ogyb2' is equivalent to '/Og' '/Oy' '/Ob2'.
+ for (Arg *A : Args) {
+ if (!A->getOption().matches(options::OPT__SLASH_O)) {
+ DAL->append(A);
+ continue;
+ }
+
+ StringRef OptStr = A->getValue();
+ for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
+ const char &OptChar = *(OptStr.data() + I);
+ switch (OptChar) {
+ default:
+ break;
+ case '1':
+ case '2':
+ case 'x':
+ case 'd':
+ if (&OptChar == ExpandChar) {
+ if (OptChar == 'd') {
+ DAL->AddFlagArg(A, Opts.getOption(options::OPT_O0));
+ } else {
+ if (OptChar == '1') {
+ DAL->AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
+ } else if (OptChar == '2' || OptChar == 'x') {
+ DAL->AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
+ DAL->AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
+ }
+ DAL->AddFlagArg(A,
+ Opts.getOption(options::OPT_fomit_frame_pointer));
+ if (OptChar == '1' || OptChar == '2')
+ DAL->AddFlagArg(A,
+ Opts.getOption(options::OPT_ffunction_sections));
+ }
+ }
+ break;
+ case 'b':
+ if (isdigit(OptStr[I + 1]))
+ ++I;
+ break;
+ case 'g':
+ break;
+ case 'i':
+ if (OptStr[I + 1] == '-') {
+ ++I;
+ DAL->AddFlagArg(A, Opts.getOption(options::OPT_fno_builtin));
+ } else {
+ DAL->AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
+ }
+ break;
+ case 's':
+ DAL->AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
+ break;
+ case 't':
+ DAL->AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
+ break;
+ case 'y':
+ if (OptStr[I + 1] == '-') {
+ ++I;
+ DAL->AddFlagArg(A,
+ Opts.getOption(options::OPT_fno_omit_frame_pointer));
+ } else {
+ DAL->AddFlagArg(A, Opts.getOption(options::OPT_fomit_frame_pointer));
+ }
+ break;
+ }
+ }
+ }
+ return DAL;
+}
diff --git a/clang/lib/Driver/ToolChains.h b/clang/lib/Driver/ToolChains.h
index 8e6267428c5..27944c8b4a6 100644
--- a/clang/lib/Driver/ToolChains.h
+++ b/clang/lib/Driver/ToolChains.h
@@ -811,6 +811,10 @@ public:
MSVCToolChain(const Driver &D, const llvm::Triple &Triple,
const llvm::opt::ArgList &Args);
+ llvm::opt::DerivedArgList *
+ TranslateArgs(const llvm::opt::DerivedArgList &Args,
+ const char *BoundArch) const override;
+
bool IsIntegratedAssemblerDefault() const override;
bool IsUnwindTablesDefault() const override;
bool isPICDefault() const override;
diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp
index 96cf7fce465..0377bc561b4 100644
--- a/clang/lib/Driver/Tools.cpp
+++ b/clang/lib/Driver/Tools.cpp
@@ -8828,17 +8828,31 @@ std::unique_ptr<Command> visualstudio::Compiler::GetCommand(
Args.AddAllArgs(CmdArgs, options::OPT_I);
// Optimization level.
+ if (Arg *A = Args.getLastArg(options::OPT_fbuiltin, options::OPT_fno_builtin))
+ CmdArgs.push_back(A->getOption().getID() == options::OPT_fbuiltin ? "/Oi"
+ : "/Oi-");
if (Arg *A = Args.getLastArg(options::OPT_O, options::OPT_O0)) {
if (A->getOption().getID() == options::OPT_O0) {
CmdArgs.push_back("/Od");
} else {
+ CmdArgs.push_back("/Og");
+
StringRef OptLevel = A->getValue();
- if (OptLevel == "1" || OptLevel == "2" || OptLevel == "s")
- A->render(Args, CmdArgs);
- else if (OptLevel == "3")
- CmdArgs.push_back("/Ox");
+ if (OptLevel == "s" || OptLevel == "z")
+ CmdArgs.push_back("/Os");
+ else
+ CmdArgs.push_back("/Ot");
+
+ CmdArgs.push_back("/Ob2");
}
}
+ if (Arg *A = Args.getLastArg(options::OPT_fomit_frame_pointer,
+ options::OPT_fno_omit_frame_pointer))
+ CmdArgs.push_back(A->getOption().getID() == options::OPT_fomit_frame_pointer
+ ? "/Oy"
+ : "/Oy-");
+ if (!Args.hasArg(options::OPT_fwritable_strings))
+ CmdArgs.push_back("/GF");
// Flags for which clang-cl has an alias.
// FIXME: How can we ensure this stays in sync with relevant clang-cl options?
OpenPOWER on IntegriCloud