diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index d30195b55881..e668bf09ad25 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -2366,15 +2366,15 @@ void Clang::DumpCompilationDatabaseFragmentToDir( DumpCompilationDatabase(C, "", Target, Output, Input, Args); } -static bool AddARMImplicitITArgs(const ArgList &Args, ArgStringList &CmdArgs, +static bool CheckARMImplicitITArg(StringRef Value) { + return Value == "always" || Value == "never" || Value == "arm" || + Value == "thumb"; +} + +static void AddARMImplicitITArgs(const ArgList &Args, ArgStringList &CmdArgs, StringRef Value) { - if (Value == "always" || Value == "never" || Value == "arm" || - Value == "thumb") { - CmdArgs.push_back("-mllvm"); - CmdArgs.push_back(Args.MakeArgString("-arm-implicit-it=" + Value)); - return true; - } - return false; + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back(Args.MakeArgString("-arm-implicit-it=" + Value)); } static void CollectArgsForIntegratedAssembler(Compilation &C, @@ -2393,22 +2393,6 @@ static void CollectArgsForIntegratedAssembler(Compilation &C, DefaultIncrementalLinkerCompatible)) CmdArgs.push_back("-mincremental-linker-compatible"); - switch (C.getDefaultToolChain().getArch()) { - case llvm::Triple::arm: - case llvm::Triple::armeb: - case llvm::Triple::thumb: - case llvm::Triple::thumbeb: - if (Arg *A = Args.getLastArg(options::OPT_mimplicit_it_EQ)) { - StringRef Value = A->getValue(); - if (!AddARMImplicitITArgs(Args, CmdArgs, Value)) - D.Diag(diag::err_drv_unsupported_option_argument) - << A->getOption().getName() << Value; - } - break; - default: - break; - } - // If you add more args here, also add them to the block below that // starts with "// If CollectArgsForIntegratedAssembler() isn't called below". @@ -2422,8 +2406,27 @@ static void CollectArgsForIntegratedAssembler(Compilation &C, bool UseRelaxRelocations = C.getDefaultToolChain().useRelaxRelocations(); bool UseNoExecStack = C.getDefaultToolChain().isNoExecStackDefault(); const char *MipsTargetFeature = nullptr; + StringRef ImplicitIt; for (const Arg *A : - Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) { + Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler, + options::OPT_mimplicit_it_EQ)) { + if (A->getOption().getID() == options::OPT_mimplicit_it_EQ) { + switch (C.getDefaultToolChain().getArch()) { + case llvm::Triple::arm: + case llvm::Triple::armeb: + case llvm::Triple::thumb: + case llvm::Triple::thumbeb: + // Only store the value; the last value set takes effect. + ImplicitIt = A->getValue(); + if (!CheckARMImplicitITArg(ImplicitIt)) + D.Diag(diag::err_drv_unsupported_option_argument) + << A->getOption().getName() << ImplicitIt; + continue; + default: + break; + } + } + A->claim(); for (StringRef Value : A->getValues()) { @@ -2444,9 +2447,12 @@ static void CollectArgsForIntegratedAssembler(Compilation &C, case llvm::Triple::thumbeb: case llvm::Triple::arm: case llvm::Triple::armeb: - if (Value.startswith("-mimplicit-it=") && - AddARMImplicitITArgs(Args, CmdArgs, Value.split("=").second)) - continue; + if (Value.startswith("-mimplicit-it=")) { + // Only store the value; the last value set takes effect. + ImplicitIt = Value.split("=").second; + if (CheckARMImplicitITArg(ImplicitIt)) + continue; + } if (Value == "-mthumb") // -mthumb has already been processed in ComputeLLVMTriple() // recognize but skip over here. @@ -2576,6 +2582,8 @@ static void CollectArgsForIntegratedAssembler(Compilation &C, } } } + if (ImplicitIt.size()) + AddARMImplicitITArgs(Args, CmdArgs, ImplicitIt); if (UseRelaxRelocations) CmdArgs.push_back("--mrelax-relocations"); if (UseNoExecStack) diff --git a/clang/test/Driver/arm-target-as-mimplicit-it.s b/clang/test/Driver/arm-target-as-mimplicit-it.s index b13b4918780c..eb02aa94e9ad 100644 --- a/clang/test/Driver/arm-target-as-mimplicit-it.s +++ b/clang/test/Driver/arm-target-as-mimplicit-it.s @@ -10,22 +10,23 @@ // RUN: %clang -target arm-linux-gnueabi -### -Xassembler -mimplicit-it=arm %s 2>&1 | FileCheck %s --check-prefix=ARM // RUN: %clang -target arm-linux-gnueabi -### -Xassembler -mimplicit-it=thumb %s 2>&1 | FileCheck %s --check-prefix=THUMB /// Test space separated -Wa,- arguments (latter wins). +// RUN: %clang -target arm-linux-gnueabi -### -Wa,-mimplicit-it=always -Wa,-mimplicit-it=always %s 2>&1 | FileCheck %s --check-prefix=ALWAYS // RUN: %clang -target arm-linux-gnueabi -### -Wa,-mimplicit-it=never -Wa,-mimplicit-it=always %s 2>&1 | FileCheck %s --check-prefix=ALWAYS // RUN: %clang -target arm-linux-gnueabi -### -Wa,-mimplicit-it=always -Wa,-mimplicit-it=never %s 2>&1 | FileCheck %s --check-prefix=NEVER // RUN: %clang -target arm-linux-gnueabi -### -Wa,-mimplicit-it=always -Wa,-mimplicit-it=arm %s 2>&1 | FileCheck %s --check-prefix=ARM // RUN: %clang -target arm-linux-gnueabi -### -Wa,-mimplicit-it=always -Wa,-mimplicit-it=thumb %s 2>&1 | FileCheck %s --check-prefix=THUMB /// Test comma separated -Wa,- arguments (latter wins). +// RUN: %clang -target arm-linux-gnueabi -### -Wa,-mimplicit-it=always,-mimplicit-it=always %s 2>&1 | FileCheck %s --check-prefix=ALWAYS // RUN: %clang -target arm-linux-gnueabi -### -Wa,-mimplicit-it=never,-mimplicit-it=always %s 2>&1 | FileCheck %s --check-prefix=ALWAYS // RUN: %clang -target arm-linux-gnueabi -### -Wa,-mimplicit-it=always,-mimplicit-it=never %s 2>&1 | FileCheck %s --check-prefix=NEVER // RUN: %clang -target arm-linux-gnueabi -### -Wa,-mimplicit-it=always,-mimplicit-it=arm %s 2>&1 | FileCheck %s --check-prefix=ARM // RUN: %clang -target arm-linux-gnueabi -### -Wa,-mimplicit-it=always,-mimplicit-it=thumb %s 2>&1 | FileCheck %s --check-prefix=THUMB -/// Mix -implicit-it= (compiler) with -Wa,-mimplicit-it= (assembler), assembler -/// takes priority. -mllvm -arm-implicit-it= will be repeated, with the -/// assembler flag appearing last (latter wins). -// RUN: %clang -target arm-linux-gnueabi -### -mimplicit-it=never -Wa,-mimplicit-it=always %S/Inputs/wildcard1.c 2>&1 | FileCheck %s --check-prefix=NEVER_ALWAYS -// RUN: %clang -target arm-linux-gnueabi -### -mimplicit-it=always -Wa,-mimplicit-it=never %S/Inputs/wildcard1.c 2>&1 | FileCheck %s --check-prefix=ALWAYS_NEVER -// RUN: %clang -target arm-linux-gnueabi -### -Wa,-mimplicit-it=never -mimplicit-it=always %S/Inputs/wildcard1.c 2>&1 | FileCheck %s --check-prefix=ALWAYS_NEVER +/// Mix -implicit-it= (compiler) with -Wa,-mimplicit-it= (assembler), the +/// last one set takes priority. +// RUN: %clang -target arm-linux-gnueabi -### -mimplicit-it=always -Wa,-mimplicit-it=always %S/Inputs/wildcard1.c 2>&1 | FileCheck %s --check-prefix=ALWAYS +// RUN: %clang -target arm-linux-gnueabi -### -mimplicit-it=never -Wa,-mimplicit-it=always %S/Inputs/wildcard1.c 2>&1 | FileCheck %s --check-prefix=ALWAYS +// RUN: %clang -target arm-linux-gnueabi -### -Wa,-mimplicit-it=never -mimplicit-it=always %S/Inputs/wildcard1.c 2>&1 | FileCheck %s --check-prefix=ALWAYS /// Test invalid input. // RUN: %clang -target arm-linux-gnueabi -### -Wa,-mimplicit-it=foo %s 2>&1 | FileCheck %s --check-prefix=INVALID @@ -34,11 +35,15 @@ // RUN: %clang -target arm-linux-gnueabi -### -Wa,-mimplicit-it=always,-mimplicit-it=foo %s 2>&1 | FileCheck %s --check-prefix=INVALID +/// Check that there isn't a second -arm-implicit-it before or after the one +/// that was the indended match. +// ALWAYS-NOT: "-arm-implicit-it={{.*}}" // ALWAYS: "-mllvm" "-arm-implicit-it=always" +// ALWAYS-NOT: "-arm-implicit-it={{.*}}" +// NEVER-NOT: "-arm-implicit-it={{.*}}" // NEVER: "-mllvm" "-arm-implicit-it=never" +// NEVER-NOT: "-arm-implicit-it={{.*}}" // ARM: "-mllvm" "-arm-implicit-it=arm" // THUMB: "-mllvm" "-arm-implicit-it=thumb" -// NEVER_ALWAYS: "-mllvm" "-arm-implicit-it=never" "-mllvm" "-arm-implicit-it=always" -// ALWAYS_NEVER: "-mllvm" "-arm-implicit-it=always" "-mllvm" "-arm-implicit-it=never" // INVALID: error: unsupported argument '-mimplicit-it=foo' to option 'Wa,' // XINVALID: error: unsupported argument '-mimplicit-it=foo' to option 'Xassembler'