diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -29,6 +29,9 @@ "invalid arch name '%0', %1">; def err_drv_invalid_riscv_ext_arch_name : Error< "invalid arch name '%0', %1 '%2'">; +def warn_drv_invalid_arch_name_with_suggestion : Warning< + "ignoring invalid /arch: argument '%0'; for %select{64|32}1-bit expected one of %2">, + InGroup; def warn_drv_avr_mcu_not_specified : Warning< "no target microcontroller specified on command line, cannot " "link standard libraries, please pass -mmcu=">, diff --git a/clang/lib/Driver/ToolChains/AVR.cpp b/clang/lib/Driver/ToolChains/AVR.cpp --- a/clang/lib/Driver/ToolChains/AVR.cpp +++ b/clang/lib/Driver/ToolChains/AVR.cpp @@ -315,7 +315,7 @@ if (!Args.hasArg(options::OPT_nostdlib) && !Args.hasArg(options::OPT_nodefaultlibs) && !Args.hasArg(options::OPT_c /* does not apply when not linking */)) { - std::string CPU = getCPUName(Args, Triple); + std::string CPU = getCPUName(D, Args, Triple); if (CPU.empty()) { // We cannot link any standard libraries without an MCU specified. @@ -389,8 +389,10 @@ const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { + const Driver &D = getToolChain().getDriver(); + // Compute information about the target AVR. - std::string CPU = getCPUName(Args, getToolChain().getTriple()); + std::string CPU = getCPUName(D, Args, getToolChain().getTriple()); llvm::Optional FamilyName = GetMCUFamilyName(CPU); llvm::Optional SectionAddressData = GetMCUSectionAddressData(CPU); @@ -414,9 +416,7 @@ CmdArgs.push_back(Args.MakeArgString(DataSectionArg)); } else { // We do not have an entry for this CPU in the address mapping table yet. - getToolChain().getDriver().Diag( - diag::warn_drv_avr_linker_section_addresses_not_implemented) - << CPU; + D.Diag(diag::warn_drv_avr_linker_section_addresses_not_implemented) << CPU; } // If the family name is known, we can link with the device-specific libgcc. diff --git a/clang/lib/Driver/ToolChains/Arch/Mips.h b/clang/lib/Driver/ToolChains/Arch/Mips.h --- a/clang/lib/Driver/ToolChains/Arch/Mips.h +++ b/clang/lib/Driver/ToolChains/Arch/Mips.h @@ -44,7 +44,8 @@ const llvm::Triple &Triple); bool hasMipsAbiArg(const llvm::opt::ArgList &Args, const char *Value); bool isUCLibc(const llvm::opt::ArgList &Args); -bool isNaN2008(const llvm::opt::ArgList &Args, const llvm::Triple &Triple); +bool isNaN2008(const Driver &D, const llvm::opt::ArgList &Args, + const llvm::Triple &Triple); bool isFP64ADefault(const llvm::Triple &Triple, StringRef CPUName); bool isFPXXDefault(const llvm::Triple &Triple, StringRef CPUName, StringRef ABIName, mips::FloatABI FloatABI); diff --git a/clang/lib/Driver/ToolChains/Arch/Mips.cpp b/clang/lib/Driver/ToolChains/Arch/Mips.cpp --- a/clang/lib/Driver/ToolChains/Arch/Mips.cpp +++ b/clang/lib/Driver/ToolChains/Arch/Mips.cpp @@ -441,7 +441,8 @@ return A && A->getOption().matches(options::OPT_muclibc); } -bool mips::isNaN2008(const ArgList &Args, const llvm::Triple &Triple) { +bool mips::isNaN2008(const Driver &D, const ArgList &Args, + const llvm::Triple &Triple) { if (Arg *NaNArg = Args.getLastArg(options::OPT_mnan_EQ)) return llvm::StringSwitch(NaNArg->getValue()) .Case("2008", true) @@ -449,7 +450,7 @@ .Default(false); // NaN2008 is the default for MIPS32r6/MIPS64r6. - return llvm::StringSwitch(getCPUName(Args, Triple)) + return llvm::StringSwitch(getCPUName(D, Args, Triple)) .Cases("mips32r6", "mips64r6", true) .Default(false); } diff --git a/clang/lib/Driver/ToolChains/Arch/X86.h b/clang/lib/Driver/ToolChains/Arch/X86.h --- a/clang/lib/Driver/ToolChains/Arch/X86.h +++ b/clang/lib/Driver/ToolChains/Arch/X86.h @@ -21,7 +21,7 @@ namespace tools { namespace x86 { -std::string getX86TargetCPU(const llvm::opt::ArgList &Args, +std::string getX86TargetCPU(const Driver &D, const llvm::opt::ArgList &Args, const llvm::Triple &Triple); void getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple, diff --git a/clang/lib/Driver/ToolChains/Arch/X86.cpp b/clang/lib/Driver/ToolChains/Arch/X86.cpp --- a/clang/lib/Driver/ToolChains/Arch/X86.cpp +++ b/clang/lib/Driver/ToolChains/Arch/X86.cpp @@ -11,6 +11,8 @@ #include "clang/Driver/Driver.h" #include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/Options.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Option/ArgList.h" #include "llvm/Support/Host.h" @@ -20,7 +22,7 @@ using namespace clang; using namespace llvm::opt; -std::string x86::getX86TargetCPU(const ArgList &Args, +std::string x86::getX86TargetCPU(const Driver &D, const ArgList &Args, const llvm::Triple &Triple) { if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_march_EQ)) { StringRef CPU = A->getValue(); @@ -37,29 +39,34 @@ return std::string(CPU); } - if (const Arg *A = Args.getLastArgNoClaim(options::OPT__SLASH_arch)) { + if (const Arg *A = Args.getLastArg(options::OPT__SLASH_arch)) { // Mapping built by looking at lib/Basic's X86TargetInfo::initFeatureMap(). - StringRef Arch = A->getValue(); - StringRef CPU; - if (Triple.getArch() == llvm::Triple::x86) { // 32-bit-only /arch: flags. - CPU = llvm::StringSwitch(Arch) - .Case("IA32", "i386") - .Case("SSE", "pentium3") - .Case("SSE2", "pentium4") - .Default(""); + // The keys are case-sensitive; this matches link.exe. + // 32-bit and 64-bit /arch: flags. + llvm::StringMap ArchMap({ + {"AVX", "sandybridge"}, + {"AVX2", "haswell"}, + {"AVX512F", "knl"}, + {"AVX512", "skylake-avx512"}, + }); + if (Triple.getArch() == llvm::Triple::x86) { + // 32-bit-only /arch: flags. + ArchMap.insert({ + {"IA32", "i386"}, + {"SSE", "pentium3"}, + {"SSE2", "pentium4"}, + }); } - if (CPU.empty()) { // 32-bit and 64-bit /arch: flags. - CPU = llvm::StringSwitch(Arch) - .Case("AVX", "sandybridge") - .Case("AVX2", "haswell") - .Case("AVX512F", "knl") - .Case("AVX512", "skylake-avx512") - .Default(""); - } - if (!CPU.empty()) { - A->claim(); - return std::string(CPU); + StringRef CPU = ArchMap.lookup(A->getValue()); + if (CPU.empty()) { + std::vector ValidArchs{ArchMap.keys().begin(), + ArchMap.keys().end()}; + sort(ValidArchs); + D.Diag(diag::warn_drv_invalid_arch_name_with_suggestion) + << A->getValue() << (Triple.getArch() == llvm::Triple::x86) + << join(ValidArchs, ", "); } + return std::string(CPU); } // Select the default CPU if none was given (or detection failed). diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -1588,8 +1588,8 @@ } namespace { -void RenderARMABI(const llvm::Triple &Triple, const ArgList &Args, - ArgStringList &CmdArgs) { +void RenderARMABI(const Driver &D, const llvm::Triple &Triple, + const ArgList &Args, ArgStringList &CmdArgs) { // Select the ABI to use. // FIXME: Support -meabi. // FIXME: Parts of this are duplicated in the backend, unify this somehow. @@ -1597,7 +1597,7 @@ if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) { ABIName = A->getValue(); } else { - std::string CPU = getCPUName(Args, Triple, /*FromAs*/ false); + std::string CPU = getCPUName(D, Args, Triple, /*FromAs*/ false); ABIName = llvm::ARM::computeDefaultTargetABI(Triple, CPU).data(); } @@ -1608,7 +1608,7 @@ void Clang::AddARMTargetArgs(const llvm::Triple &Triple, const ArgList &Args, ArgStringList &CmdArgs, bool KernelOrKext) const { - RenderARMABI(Triple, Args, CmdArgs); + RenderARMABI(getToolChain().getDriver(), Triple, Args, CmdArgs); // Determine floating point ABI from the options & target defaults. arm::FloatABI ABI = arm::getARMFloatABI(getToolChain(), Args); @@ -4595,7 +4595,7 @@ case llvm::Triple::arm: case llvm::Triple::armeb: case llvm::Triple::thumbeb: - RenderARMABI(Triple, Args, CmdArgs); + RenderARMABI(D, Triple, Args, CmdArgs); break; case llvm::Triple::aarch64: case llvm::Triple::aarch64_32: @@ -5132,7 +5132,7 @@ const ArgList &HostArgs = C.getArgsForToolChain(nullptr, StringRef(), Action::OFK_None); std::string HostCPU = - getCPUName(HostArgs, *TC.getAuxTriple(), /*FromAs*/ false); + getCPUName(D, HostArgs, *TC.getAuxTriple(), /*FromAs*/ false); if (!HostCPU.empty()) { CmdArgs.push_back("-aux-target-cpu"); CmdArgs.push_back(Args.MakeArgString(HostCPU)); @@ -5174,7 +5174,7 @@ } // Add the target cpu - std::string CPU = getCPUName(Args, Triple, /*FromAs*/ false); + std::string CPU = getCPUName(D, Args, Triple, /*FromAs*/ false); if (!CPU.empty()) { CmdArgs.push_back("-target-cpu"); CmdArgs.push_back(Args.MakeArgString(CPU)); @@ -7450,7 +7450,7 @@ CmdArgs.push_back(Clang::getBaseInputName(Args, Input)); // Add the target cpu - std::string CPU = getCPUName(Args, Triple, /*FromAs*/ true); + std::string CPU = getCPUName(D, Args, Triple, /*FromAs*/ true); if (!CPU.empty()) { CmdArgs.push_back("-target-cpu"); CmdArgs.push_back(Args.MakeArgString(CPU)); diff --git a/clang/lib/Driver/ToolChains/CommonArgs.h b/clang/lib/Driver/ToolChains/CommonArgs.h --- a/clang/lib/Driver/ToolChains/CommonArgs.h +++ b/clang/lib/Driver/ToolChains/CommonArgs.h @@ -107,8 +107,8 @@ llvm::opt::OptSpecifier OnOpt, llvm::opt::OptSpecifier OffOpt, StringRef FeatureName); -std::string getCPUName(const llvm::opt::ArgList &Args, const llvm::Triple &T, - bool FromAs = false); +std::string getCPUName(const Driver &D, const llvm::opt::ArgList &Args, + const llvm::Triple &T, bool FromAs = false); /// Iterate \p Args and convert -mxxx to +xxx and -mno-xxx to -xxx and /// append it to \p Features. diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -355,8 +355,8 @@ return "generic"; } -std::string tools::getCPUName(const ArgList &Args, const llvm::Triple &T, - bool FromAs) { +std::string tools::getCPUName(const Driver &D, const ArgList &Args, + const llvm::Triple &T, bool FromAs) { Arg *A; switch (T.getArch()) { @@ -442,7 +442,7 @@ case llvm::Triple::x86: case llvm::Triple::x86_64: - return x86::getX86TargetCPU(Args, T); + return x86::getX86TargetCPU(D, Args, T); case llvm::Triple::hexagon: return "hexagon" + @@ -510,7 +510,7 @@ // the plugin. // Handle flags for selecting CPU variants. - std::string CPU = getCPUName(Args, ToolChain.getTriple()); + std::string CPU = getCPUName(D, Args, ToolChain.getTriple()); if (!CPU.empty()) CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-opt=mcpu=") + CPU)); diff --git a/clang/lib/Driver/ToolChains/FreeBSD.cpp b/clang/lib/Driver/ToolChains/FreeBSD.cpp --- a/clang/lib/Driver/ToolChains/FreeBSD.cpp +++ b/clang/lib/Driver/ToolChains/FreeBSD.cpp @@ -99,7 +99,7 @@ case llvm::Triple::sparc: case llvm::Triple::sparcel: case llvm::Triple::sparcv9: { - std::string CPU = getCPUName(Args, getToolChain().getTriple()); + std::string CPU = getCPUName(D, Args, getToolChain().getTriple()); CmdArgs.push_back( sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple())); AddAssemblerKPIC(getToolChain(), Args, CmdArgs); diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -451,7 +451,7 @@ // Most Android ARM64 targets should enable the linker fix for erratum // 843419. Only non-Cortex-A53 devices are allowed to skip this flag. if (Arch == llvm::Triple::aarch64 && isAndroid) { - std::string CPU = getCPUName(Args, Triple); + std::string CPU = getCPUName(D, Args, Triple); if (CPU.empty() || CPU == "generic" || CPU == "cortex-a53") CmdArgs.push_back("--fix-cortex-a53-843419"); } @@ -734,32 +734,32 @@ CmdArgs.push_back("-a32"); CmdArgs.push_back("-mppc"); CmdArgs.push_back("-mbig-endian"); - CmdArgs.push_back( - ppc::getPPCAsmModeForCPU(getCPUName(Args, getToolChain().getTriple()))); + CmdArgs.push_back(ppc::getPPCAsmModeForCPU( + getCPUName(D, Args, getToolChain().getTriple()))); break; } case llvm::Triple::ppcle: { CmdArgs.push_back("-a32"); CmdArgs.push_back("-mppc"); CmdArgs.push_back("-mlittle-endian"); - CmdArgs.push_back( - ppc::getPPCAsmModeForCPU(getCPUName(Args, getToolChain().getTriple()))); + CmdArgs.push_back(ppc::getPPCAsmModeForCPU( + getCPUName(D, Args, getToolChain().getTriple()))); break; } case llvm::Triple::ppc64: { CmdArgs.push_back("-a64"); CmdArgs.push_back("-mppc64"); CmdArgs.push_back("-mbig-endian"); - CmdArgs.push_back( - ppc::getPPCAsmModeForCPU(getCPUName(Args, getToolChain().getTriple()))); + CmdArgs.push_back(ppc::getPPCAsmModeForCPU( + getCPUName(D, Args, getToolChain().getTriple()))); break; } case llvm::Triple::ppc64le: { CmdArgs.push_back("-a64"); CmdArgs.push_back("-mppc64"); CmdArgs.push_back("-mlittle-endian"); - CmdArgs.push_back( - ppc::getPPCAsmModeForCPU(getCPUName(Args, getToolChain().getTriple()))); + CmdArgs.push_back(ppc::getPPCAsmModeForCPU( + getCPUName(D, Args, getToolChain().getTriple()))); break; } case llvm::Triple::riscv32: @@ -775,7 +775,7 @@ case llvm::Triple::sparc: case llvm::Triple::sparcel: { CmdArgs.push_back("-32"); - std::string CPU = getCPUName(Args, getToolChain().getTriple()); + std::string CPU = getCPUName(D, Args, getToolChain().getTriple()); CmdArgs.push_back( sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple())); AddAssemblerKPIC(getToolChain(), Args, CmdArgs); @@ -783,7 +783,7 @@ } case llvm::Triple::sparcv9: { CmdArgs.push_back("-64"); - std::string CPU = getCPUName(Args, getToolChain().getTriple()); + std::string CPU = getCPUName(D, Args, getToolChain().getTriple()); CmdArgs.push_back( sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple())); AddAssemblerKPIC(getToolChain(), Args, CmdArgs); @@ -1473,7 +1473,7 @@ addMultilibFlag(CPUName == "mips64r6", "march=mips64r6", Flags); addMultilibFlag(isMicroMips(Args), "mmicromips", Flags); addMultilibFlag(tools::mips::isUCLibc(Args), "muclibc", Flags); - addMultilibFlag(tools::mips::isNaN2008(Args, TargetTriple), "mnan=2008", + addMultilibFlag(tools::mips::isNaN2008(D, Args, TargetTriple), "mnan=2008", Flags); addMultilibFlag(ABIName == "n32", "mabi=n32", Flags); addMultilibFlag(ABIName == "n64", "mabi=n64", Flags); diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp --- a/clang/lib/Driver/ToolChains/Linux.cpp +++ b/clang/lib/Driver/ToolChains/Linux.cpp @@ -453,7 +453,7 @@ case llvm::Triple::mipsel: case llvm::Triple::mips64: case llvm::Triple::mips64el: { - bool IsNaN2008 = tools::mips::isNaN2008(Args, Triple); + bool IsNaN2008 = tools::mips::isNaN2008(getDriver(), Args, Triple); LibDir = "lib" + tools::mips::getMipsABILibSuffix(Args, Triple); diff --git a/clang/lib/Driver/ToolChains/NetBSD.cpp b/clang/lib/Driver/ToolChains/NetBSD.cpp --- a/clang/lib/Driver/ToolChains/NetBSD.cpp +++ b/clang/lib/Driver/ToolChains/NetBSD.cpp @@ -29,6 +29,8 @@ const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { + const Driver &D = getToolChain().getDriver(); + claimNoWarnArgs(Args); ArgStringList CmdArgs; @@ -76,16 +78,18 @@ case llvm::Triple::sparc: case llvm::Triple::sparcel: { CmdArgs.push_back("-32"); - std::string CPU = getCPUName(Args, getToolChain().getTriple()); - CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple())); + std::string CPU = getCPUName(D, Args, getToolChain().getTriple()); + CmdArgs.push_back( + sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple())); AddAssemblerKPIC(getToolChain(), Args, CmdArgs); break; } case llvm::Triple::sparcv9: { CmdArgs.push_back("-64"); - std::string CPU = getCPUName(Args, getToolChain().getTriple()); - CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple())); + std::string CPU = getCPUName(D, Args, getToolChain().getTriple()); + CmdArgs.push_back( + sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple())); AddAssemblerKPIC(getToolChain(), Args, CmdArgs); break; } diff --git a/clang/lib/Driver/ToolChains/OpenBSD.cpp b/clang/lib/Driver/ToolChains/OpenBSD.cpp --- a/clang/lib/Driver/ToolChains/OpenBSD.cpp +++ b/clang/lib/Driver/ToolChains/OpenBSD.cpp @@ -45,8 +45,10 @@ case llvm::Triple::sparcv9: { CmdArgs.push_back("-64"); - std::string CPU = getCPUName(Args, getToolChain().getTriple()); - CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple())); + std::string CPU = getCPUName(getToolChain().getDriver(), Args, + getToolChain().getTriple()); + CmdArgs.push_back( + sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple())); AddAssemblerKPIC(getToolChain(), Args, CmdArgs); break; } diff --git a/clang/test/Driver/cl-x86-flags.c b/clang/test/Driver/cl-x86-flags.c --- a/clang/test/Driver/cl-x86-flags.c +++ b/clang/test/Driver/cl-x86-flags.c @@ -6,7 +6,8 @@ // flag space. // RUN: %clang_cl /Zs /WX -m32 -m64 -msse3 -msse4.1 -mavx -mno-avx \ // RUN: --target=i386-pc-win32 -### -- 2>&1 %s | FileCheck -check-prefix=MFLAGS %s -// MFLAGS-NOT: argument unused during compilation +// MFLAGS-NOT: invalid /arch: argument +// // RUN: %clang_cl -m32 -arch:IA32 --target=i386-pc-windows /c /Fo%t.obj -Xclang -verify -DTEST_32_ARCH_IA32 -- %s #if defined(TEST_32_ARCH_IA32) @@ -17,10 +18,10 @@ // arch: args are case-sensitive. // RUN: %clang_cl -m32 -arch:ia32 --target=i386-pc-windows -### -- 2>&1 %s | FileCheck -check-prefix=ia32 %s -// ia32: argument unused during compilation +// ia32: invalid /arch: argument 'ia32'; for 32-bit expected one of AVX, AVX2, AVX512, AVX512F, IA32, SSE, SSE2 // RUN: %clang_cl -m64 -arch:IA32 --target=x86_64-pc-windows -### -- 2>&1 %s | FileCheck -check-prefix=IA3264 %s -// IA3264: argument unused during compilation +// IA3264: invalid /arch: argument 'IA32'; for 64-bit expected one of AVX, AVX2, AVX512, AVX512F // RUN: %clang_cl -m32 -arch:SSE --target=i386-pc-windows /c /Fo%t.obj -Xclang -verify -DTEST_32_ARCH_SSE -- %s #if defined(TEST_32_ARCH_SSE) @@ -30,7 +31,7 @@ #endif // RUN: %clang_cl -m32 -arch:sse --target=i386-pc-windows -### -- 2>&1 %s | FileCheck -check-prefix=sse %s -// sse: argument unused during compilation +// sse: invalid /arch: argument // RUN: %clang_cl -m32 -arch:SSE2 --target=i386-pc-windows /c /Fo%t.obj -Xclang -verify -DTEST_32_ARCH_SSE2 -- %s #if defined(TEST_32_ARCH_SSE2) @@ -40,13 +41,13 @@ #endif // RUN: %clang_cl -m32 -arch:sse2 --target=i386-pc-windows -### -- 2>&1 %s | FileCheck -check-prefix=sse %s -// sse2: argument unused during compilation +// sse2: invalid /arch: argument // RUN: %clang_cl -m64 -arch:SSE --target=x86_64-pc-windows -### -- 2>&1 %s | FileCheck -check-prefix=SSE64 %s -// SSE64: argument unused during compilation +// SSE64: invalid /arch: argument 'SSE'; for 64-bit expected one of AVX, AVX2, AVX512, AVX512F // RUN: %clang_cl -m64 -arch:SSE2 --target=x86_64-pc-windows -### -- 2>&1 %s | FileCheck -check-prefix=SSE264 %s -// SSE264: argument unused during compilation +// SSE264: invalid /arch: argument // RUN: %clang_cl -m32 -arch:AVX --target=i386-pc-windows /c /Fo%t.obj -Xclang -verify -DTEST_32_ARCH_AVX -- %s #if defined(TEST_32_ARCH_AVX) @@ -56,7 +57,7 @@ #endif // RUN: %clang_cl -m32 -arch:avx --target=i386-pc-windows -### -- 2>&1 %s | FileCheck -check-prefix=avx %s -// avx: argument unused during compilation +// avx: invalid /arch: argument // RUN: %clang_cl -m32 -arch:AVX2 --target=i386-pc-windows /c /Fo%t.obj -Xclang -verify -DTEST_32_ARCH_AVX2 -- %s #if defined(TEST_32_ARCH_AVX2) @@ -66,7 +67,7 @@ #endif // RUN: %clang_cl -m32 -arch:avx2 --target=i386-pc-windows -### -- 2>&1 %s | FileCheck -check-prefix=avx2 %s -// avx2: argument unused during compilation +// avx2: invalid /arch: argument // RUN: %clang_cl -m32 -arch:AVX512F --target=i386-pc-windows /c /Fo%t.obj -Xclang -verify -DTEST_32_ARCH_AVX512F -- %s #if defined(TEST_32_ARCH_AVX512F) @@ -76,7 +77,7 @@ #endif // RUN: %clang_cl -m32 -arch:avx512f --target=i386-pc-windows -### -- 2>&1 %s | FileCheck -check-prefix=avx512f %s -// avx512f: argument unused during compilation +// avx512f: invalid /arch: argument // RUN: %clang_cl -m32 -arch:AVX512 --target=i386-pc-windows /c /Fo%t.obj -Xclang -verify -DTEST_32_ARCH_AVX512 -- %s #if defined(TEST_32_ARCH_AVX512) @@ -86,7 +87,7 @@ #endif // RUN: %clang_cl -m32 -arch:avx512 --target=i386-pc-windows -### -- 2>&1 %s | FileCheck -check-prefix=avx512 %s -// avx512: argument unused during compilation +// avx512: invalid /arch: argument // RUN: %clang_cl -m64 -arch:AVX --target=x86_64-pc-windows /c /Fo%t.obj -Xclang -verify -DTEST_64_ARCH_AVX -- %s #if defined(TEST_64_ARCH_AVX) @@ -96,7 +97,7 @@ #endif // RUN: %clang_cl -m64 -arch:avx --target=x86_64-pc-windows -### -- 2>&1 %s | FileCheck -check-prefix=avx64 %s -// avx64: argument unused during compilation +// avx64: invalid /arch: argument // RUN: %clang_cl -m64 -arch:AVX2 --target=x86_64-pc-windows /c /Fo%t.obj -Xclang -verify -DTEST_64_ARCH_AVX2 -- %s #if defined(TEST_64_ARCH_AVX2) @@ -106,7 +107,7 @@ #endif // RUN: %clang_cl -m64 -arch:avx2 --target=x86_64-pc-windows -### -- 2>&1 %s | FileCheck -check-prefix=avx264 %s -// avx264: argument unused during compilation +// avx264: invalid /arch: argument // RUN: %clang_cl -m64 -arch:AVX512F --target=i386-pc-windows /c /Fo%t.obj -Xclang -verify -DTEST_64_ARCH_AVX512F -- %s #if defined(TEST_64_ARCH_AVX512F) @@ -116,7 +117,7 @@ #endif // RUN: %clang_cl -m64 -arch:avx512f --target=i386-pc-windows -### -- 2>&1 %s | FileCheck -check-prefix=avx512f64 %s -// avx512f64: argument unused during compilation +// avx512f64: invalid /arch: argument // RUN: %clang_cl -m64 -arch:AVX512 --target=i386-pc-windows /c /Fo%t.obj -Xclang -verify -DTEST_64_ARCH_AVX512 -- %s #if defined(TEST_64_ARCH_AVX512) @@ -126,7 +127,7 @@ #endif // RUN: %clang_cl -m64 -arch:avx512 --target=i386-pc-windows -### -- 2>&1 %s | FileCheck -check-prefix=avx51264 %s -// avx51264: argument unused during compilation +// avx51264: invalid /arch: argument // RUN: %clang_cl -m64 -arch:AVX -tune:haswell --target=x86_64-pc-windows -### -- 2>&1 %s | FileCheck -check-prefix=tune %s // tune: "-target-cpu" "sandybridge" diff --git a/llvm/include/llvm/ADT/StringMap.h b/llvm/include/llvm/ADT/StringMap.h --- a/llvm/include/llvm/ADT/StringMap.h +++ b/llvm/include/llvm/ADT/StringMap.h @@ -126,9 +126,7 @@ StringMap(std::initializer_list> List) : StringMapImpl(List.size(), static_cast(sizeof(MapEntryTy))) { - for (const auto &P : List) { - insert(P); - } + insert(List); } StringMap(StringMap &&RHS) @@ -297,6 +295,21 @@ return try_emplace(KV.first, std::move(KV.second)); } + /// Inserts elements from range [first, last). If multiple elements in the + /// range have keys that compare equivalent, it is unspecified which element + /// is inserted . + template void insert(InputIt First, InputIt Last) { + for (InputIt It = First; It != Last; ++It) + insert(*It); + } + + /// Inserts elements from initializer list ilist. If multiple elements in + /// the range have keys that compare equivalent, it is unspecified which + /// element is inserted + void insert(std::initializer_list> List) { + insert(List.begin(), List.end()); + } + /// Inserts an element or assigns to the current element if the key already /// exists. The return type is the same as try_emplace. template diff --git a/llvm/unittests/ADT/StringMapTest.cpp b/llvm/unittests/ADT/StringMapTest.cpp --- a/llvm/unittests/ADT/StringMapTest.cpp +++ b/llvm/unittests/ADT/StringMapTest.cpp @@ -111,6 +111,13 @@ EXPECT_TRUE(constTestMap.find(testKeyStr) == constTestMap.end()); } +// initializer_list ctor test; also implicitly tests initializer_list and +// iterator overloads of insert(). +TEST_F(StringMapTest, InitializerListCtor) { + testMap = StringMap({{"key", 1}}); + assertSingleItemMap(); +} + // A map with a single entry. TEST_F(StringMapTest, SingleEntryMapTest) { testMap[testKey] = testValue;