[clang-cl] Emit nicer warning on unknown /arch: arguments

Now prints the list of known archs. This requires plumbing a Driver
arg through a few functions.

Also add two more convenience insert() overlods to StringMap.

Differential Revision: https://reviews.llvm.org/D109105
This commit is contained in:
Nico Weber 2021-09-01 18:40:05 -04:00
parent 711aa35759
commit 973519826e
17 changed files with 121 additions and 82 deletions

View File

@ -29,6 +29,9 @@ def err_drv_invalid_riscv_arch_name : Error<
"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<UnusedCommandLineArgument>;
def warn_drv_avr_mcu_not_specified : Warning<
"no target microcontroller specified on command line, cannot "
"link standard libraries, please pass -mmcu=<mcu name>">,

View File

@ -315,7 +315,7 @@ AVRToolChain::AVRToolChain(const Driver &D, const llvm::Triple &Triple,
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 @@ void AVR::Linker::ConstructJob(Compilation &C, const JobAction &JA,
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<StringRef> FamilyName = GetMCUFamilyName(CPU);
llvm::Optional<unsigned> SectionAddressData = GetMCUSectionAddressData(CPU);
@ -414,9 +416,7 @@ void AVR::Linker::ConstructJob(Compilation &C, const JobAction &JA,
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.

View File

@ -441,7 +441,8 @@ bool mips::isUCLibc(const ArgList &Args) {
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<bool>(NaNArg->getValue())
.Case("2008", true)
@ -449,7 +450,7 @@ bool mips::isNaN2008(const ArgList &Args, const llvm::Triple &Triple) {
.Default(false);
// NaN2008 is the default for MIPS32r6/MIPS64r6.
return llvm::StringSwitch<bool>(getCPUName(Args, Triple))
return llvm::StringSwitch<bool>(getCPUName(D, Args, Triple))
.Cases("mips32r6", "mips64r6", true)
.Default(false);
}

View File

@ -44,7 +44,8 @@ std::string getMipsABILibSuffix(const llvm::opt::ArgList &Args,
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);

View File

@ -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::driver::tools;
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 @@ std::string x86::getX86TargetCPU(const ArgList &Args,
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<StringRef>(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<StringRef> 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<StringRef>(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<StringRef> 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).

View File

@ -21,7 +21,7 @@ namespace driver {
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,

View File

@ -1588,8 +1588,8 @@ void AddAAPCSVolatileBitfieldArgs(const ArgList &Args, ArgStringList &CmdArgs) {
}
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 @@ void RenderARMABI(const llvm::Triple &Triple, const ArgList &Args,
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 RenderARMABI(const llvm::Triple &Triple, const ArgList &Args,
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 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
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 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
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 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
}
// 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 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
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));

View File

@ -355,8 +355,8 @@ static StringRef getWebAssemblyTargetCPU(const ArgList &Args) {
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 @@ std::string tools::getCPUName(const ArgList &Args, const llvm::Triple &T,
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 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args,
// 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));

View File

@ -107,8 +107,8 @@ void AddTargetFeature(const llvm::opt::ArgList &Args,
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.

View File

@ -99,7 +99,7 @@ void freebsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
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);

View File

@ -451,7 +451,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
// 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 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C,
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 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C,
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 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C,
}
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 @@ bool clang::driver::findMIPSMultilibs(const Driver &D,
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);

View File

@ -453,7 +453,7 @@ std::string Linux::getDynamicLinker(const ArgList &Args) const {
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);

View File

@ -29,6 +29,8 @@ void netbsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfoList &Inputs,
const ArgList &Args,
const char *LinkingOutput) const {
const Driver &D = getToolChain().getDriver();
claimNoWarnArgs(Args);
ArgStringList CmdArgs;
@ -76,16 +78,18 @@ void netbsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
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;
}

View File

@ -45,8 +45,10 @@ void openbsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
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;
}

View File

@ -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"

View File

@ -126,9 +126,7 @@ public:
StringMap(std::initializer_list<std::pair<StringRef, ValueTy>> List)
: StringMapImpl(List.size(), static_cast<unsigned>(sizeof(MapEntryTy))) {
for (const auto &P : List) {
insert(P);
}
insert(List);
}
StringMap(StringMap &&RHS)
@ -297,6 +295,21 @@ public:
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 <typename InputIt> 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<std::pair<StringRef, ValueTy>> 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 <typename V>

View File

@ -111,6 +111,13 @@ TEST_F(StringMapTest, ConstEmptyMapTest) {
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<uint32_t>({{"key", 1}});
assertSingleItemMap();
}
// A map with a single entry.
TEST_F(StringMapTest, SingleEntryMapTest) {
testMap[testKey] = testValue;