[clang][Driver] Add a custom error option in multilib.yaml. (#105684)
Sometimes a collection of multilibs has a gap in it, where a set of driver command-line options can't work with any of the available libraries. For example, the Arm MVE extension requires special startup code (you need to initialize FPSCR.LTPSIZE), and also benefits greatly from -mfloat-abi=hard. So a multilib provider might build a library for systems without MVE, and another for MVE with -mfloat-abi=hard, anticipating that that's what most MVE users would want. But then if a user compiles for MVE _without_ -mfloat-abi=hard, thhey can't use either of those libraries – one has an ABI mismatch, and the other will fail to set up LTPSIZE. In that situation, it's useful to include a multilib.yaml entry for the unworkable intermediate situation, and have it map to a fatal error message rather than a set of actual libraries. Then the user gets a build failure with a sensible explanation, instead of selecting an unworkable library and silently generating bad output. The new regression test demonstrates this case. This patch introduces extra syntax into multilib.yaml, so that a record in the `Variants` list can omit the `Dir` key, and in its place, provide a `FatalError` key. Then, if that variant is selected, the error message is emitted as a clang diagnostic, and multilib selection fails. In order to emit the error message in `MultilibSet::select`, I had to pass a `Driver &` to that function, which involved plumbing one through to every call site, and in the unit tests, constructing one specially.
This commit is contained in:
parent
30d56bedd0
commit
26bf0b4ae7
13 changed files with 237 additions and 86 deletions
|
|
@ -200,6 +200,12 @@ For a more comprehensive example see
|
|||
# to be a match.
|
||||
Flags: [--target=thumbv7m-none-eabi, -mfpu=fpv4-sp-d16]
|
||||
|
||||
# If there is no multilib available for a particular set of flags, and the
|
||||
# other multilibs are not adequate fallbacks, then you can define a variant
|
||||
# record with a FatalError key in place of the Dir key.
|
||||
- FatalError: this multilib collection has no hard-float ABI support
|
||||
Flags: [--target=thumbv7m-none-eabi, -mfloat-abi=hard]
|
||||
|
||||
|
||||
# The second section of the file is a list of regular expressions that are
|
||||
# used to map from flags generated from command line options to custom flags.
|
||||
|
|
|
|||
|
|
@ -810,6 +810,8 @@ def warn_drv_missing_multilib : Warning<
|
|||
InGroup<DiagGroup<"missing-multilib">>;
|
||||
def note_drv_available_multilibs : Note<
|
||||
"available multilibs are:%0">;
|
||||
def err_drv_multilib_custom_error : Error<
|
||||
"multilib configuration error: %0">;
|
||||
|
||||
def err_drv_experimental_crel : Error<
|
||||
"-Wa,--allow-experimental-crel must be specified to use -Wa,--crel. "
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include "llvm/Support/SourceMgr.h"
|
||||
#include <cassert>
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
|
@ -25,6 +26,8 @@
|
|||
namespace clang {
|
||||
namespace driver {
|
||||
|
||||
class Driver;
|
||||
|
||||
/// This corresponds to a single GCC Multilib, or a segment of one controlled
|
||||
/// by a command line flag.
|
||||
/// See also MultilibBuilder for building a multilib by mutating it
|
||||
|
|
@ -48,13 +51,19 @@ private:
|
|||
// directory is not mutually exclusive with anything else.
|
||||
std::string ExclusiveGroup;
|
||||
|
||||
// Some Multilib objects don't actually represent library directories you can
|
||||
// select. Instead, they represent failures of multilib selection, of the
|
||||
// form 'Sorry, we don't have any library compatible with these constraints'.
|
||||
std::optional<std::string> FatalError;
|
||||
|
||||
public:
|
||||
/// GCCSuffix, OSSuffix & IncludeSuffix will be appended directly to the
|
||||
/// sysroot string so they must either be empty or begin with a '/' character.
|
||||
/// This is enforced with an assert in the constructor.
|
||||
Multilib(StringRef GCCSuffix = {}, StringRef OSSuffix = {},
|
||||
StringRef IncludeSuffix = {}, const flags_list &Flags = flags_list(),
|
||||
StringRef ExclusiveGroup = {});
|
||||
StringRef ExclusiveGroup = {},
|
||||
std::optional<StringRef> FatalError = std::nullopt);
|
||||
|
||||
/// Get the detected GCC installation path suffix for the multi-arch
|
||||
/// target variant. Always starts with a '/', unless empty
|
||||
|
|
@ -84,6 +93,10 @@ public:
|
|||
{ return GCCSuffix.empty() && OSSuffix.empty() && IncludeSuffix.empty(); }
|
||||
|
||||
bool operator==(const Multilib &Other) const;
|
||||
|
||||
bool isFatalError() const { return FatalError.has_value(); }
|
||||
|
||||
const std::string &getFatalError() const { return FatalError.value(); }
|
||||
};
|
||||
|
||||
raw_ostream &operator<<(raw_ostream &OS, const Multilib &M);
|
||||
|
|
@ -129,7 +142,7 @@ public:
|
|||
const_iterator end() const { return Multilibs.end(); }
|
||||
|
||||
/// Select compatible variants, \returns false if none are compatible
|
||||
bool select(const Multilib::flags_list &Flags,
|
||||
bool select(const Driver &D, const Multilib::flags_list &Flags,
|
||||
llvm::SmallVectorImpl<Multilib> &) const;
|
||||
|
||||
unsigned size() const { return Multilibs.size(); }
|
||||
|
|
|
|||
|
|
@ -2296,7 +2296,8 @@ bool Driver::HandleImmediateArgs(Compilation &C) {
|
|||
|
||||
if (C.getArgs().hasArg(options::OPT_print_multi_lib)) {
|
||||
for (const Multilib &Multilib : TC.getMultilibs())
|
||||
llvm::outs() << Multilib << "\n";
|
||||
if (!Multilib.isFatalError())
|
||||
llvm::outs() << Multilib << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include "clang/Driver/Multilib.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "clang/Basic/Version.h"
|
||||
#include "clang/Driver/Driver.h"
|
||||
#include "llvm/ADT/DenseSet.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
|
|
@ -31,9 +32,10 @@ using namespace llvm::sys;
|
|||
|
||||
Multilib::Multilib(StringRef GCCSuffix, StringRef OSSuffix,
|
||||
StringRef IncludeSuffix, const flags_list &Flags,
|
||||
StringRef ExclusiveGroup)
|
||||
StringRef ExclusiveGroup,
|
||||
std::optional<StringRef> FatalError)
|
||||
: GCCSuffix(GCCSuffix), OSSuffix(OSSuffix), IncludeSuffix(IncludeSuffix),
|
||||
Flags(Flags), ExclusiveGroup(ExclusiveGroup) {
|
||||
Flags(Flags), ExclusiveGroup(ExclusiveGroup), FatalError(FatalError) {
|
||||
assert(GCCSuffix.empty() ||
|
||||
(StringRef(GCCSuffix).front() == '/' && GCCSuffix.size() > 1));
|
||||
assert(OSSuffix.empty() ||
|
||||
|
|
@ -94,7 +96,7 @@ MultilibSet &MultilibSet::FilterOut(FilterCallback F) {
|
|||
|
||||
void MultilibSet::push_back(const Multilib &M) { Multilibs.push_back(M); }
|
||||
|
||||
bool MultilibSet::select(const Multilib::flags_list &Flags,
|
||||
bool MultilibSet::select(const Driver &D, const Multilib::flags_list &Flags,
|
||||
llvm::SmallVectorImpl<Multilib> &Selected) const {
|
||||
llvm::StringSet<> FlagSet(expandFlags(Flags));
|
||||
Selected.clear();
|
||||
|
|
@ -121,6 +123,14 @@ bool MultilibSet::select(const Multilib::flags_list &Flags,
|
|||
continue;
|
||||
}
|
||||
|
||||
// If this multilib is actually a placeholder containing a fatal
|
||||
// error message written by the multilib.yaml author, display that
|
||||
// error message, and return failure.
|
||||
if (M.isFatalError()) {
|
||||
D.Diag(clang::diag::err_drv_multilib_custom_error) << M.getFatalError();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Select this multilib.
|
||||
Selected.push_back(M);
|
||||
}
|
||||
|
|
@ -162,7 +172,8 @@ namespace {
|
|||
static const VersionTuple MultilibVersionCurrent(1, 0);
|
||||
|
||||
struct MultilibSerialization {
|
||||
std::string Dir;
|
||||
std::string Dir; // if this record successfully selects a library dir
|
||||
std::string FatalError; // if this record reports a fatal error message
|
||||
std::vector<std::string> Flags;
|
||||
std::string Group;
|
||||
};
|
||||
|
|
@ -205,11 +216,16 @@ struct MultilibSetSerialization {
|
|||
|
||||
template <> struct llvm::yaml::MappingTraits<MultilibSerialization> {
|
||||
static void mapping(llvm::yaml::IO &io, MultilibSerialization &V) {
|
||||
io.mapRequired("Dir", V.Dir);
|
||||
io.mapOptional("Dir", V.Dir);
|
||||
io.mapOptional("FatalError", V.FatalError);
|
||||
io.mapRequired("Flags", V.Flags);
|
||||
io.mapOptional("Group", V.Group);
|
||||
}
|
||||
static std::string validate(IO &io, MultilibSerialization &V) {
|
||||
if (V.Dir.empty() && V.FatalError.empty())
|
||||
return "one of the 'Dir' and 'FatalError' keys must be specified";
|
||||
if (!V.Dir.empty() && !V.FatalError.empty())
|
||||
return "the 'Dir' and 'FatalError' keys may not both be specified";
|
||||
if (StringRef(V.Dir).starts_with("/"))
|
||||
return "paths must be relative but \"" + V.Dir + "\" starts with \"/\"";
|
||||
return std::string{};
|
||||
|
|
@ -295,14 +311,18 @@ MultilibSet::parseYaml(llvm::MemoryBufferRef Input,
|
|||
multilib_list Multilibs;
|
||||
Multilibs.reserve(MS.Multilibs.size());
|
||||
for (const auto &M : MS.Multilibs) {
|
||||
std::string Dir;
|
||||
if (M.Dir != ".")
|
||||
Dir = "/" + M.Dir;
|
||||
// We transfer M.Group straight into the ExclusiveGroup parameter for the
|
||||
// Multilib constructor. If we later support more than one type of group,
|
||||
// we'll have to look up the group name in MS.Groups, check its type, and
|
||||
// decide what to do here.
|
||||
Multilibs.emplace_back(Dir, Dir, Dir, M.Flags, M.Group);
|
||||
if (!M.FatalError.empty()) {
|
||||
Multilibs.emplace_back("", "", "", M.Flags, M.Group, M.FatalError);
|
||||
} else {
|
||||
std::string Dir;
|
||||
if (M.Dir != ".")
|
||||
Dir = "/" + M.Dir;
|
||||
// We transfer M.Group straight into the ExclusiveGroup parameter for the
|
||||
// Multilib constructor. If we later support more than one type of group,
|
||||
// we'll have to look up the group name in MS.Groups, check its type, and
|
||||
// decide what to do here.
|
||||
Multilibs.emplace_back(Dir, Dir, Dir, M.Flags, M.Group);
|
||||
}
|
||||
}
|
||||
|
||||
return MultilibSet(std::move(Multilibs), std::move(MS.FlagMatchers));
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ static bool findRISCVMultilibs(const Driver &D,
|
|||
|
||||
Result.Multilibs =
|
||||
MultilibSetBuilder().Either(Imac, Imafdc).makeMultilibSet();
|
||||
return Result.Multilibs.select(Flags, Result.SelectedMultilibs);
|
||||
return Result.Multilibs.select(D, Flags, Result.SelectedMultilibs);
|
||||
}
|
||||
if (TargetTriple.isRISCV32()) {
|
||||
MultilibBuilder Imac =
|
||||
|
|
@ -92,7 +92,7 @@ static bool findRISCVMultilibs(const Driver &D,
|
|||
|
||||
Result.Multilibs =
|
||||
MultilibSetBuilder().Either(I, Im, Iac, Imac, Imafc).makeMultilibSet();
|
||||
return Result.Multilibs.select(Flags, Result.SelectedMultilibs);
|
||||
return Result.Multilibs.select(D, Flags, Result.SelectedMultilibs);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -182,12 +182,13 @@ static void findMultilibsFromYAML(const ToolChain &TC, const Driver &D,
|
|||
if (ErrorOrMultilibSet.getError())
|
||||
return;
|
||||
Result.Multilibs = ErrorOrMultilibSet.get();
|
||||
if (Result.Multilibs.select(Flags, Result.SelectedMultilibs))
|
||||
if (Result.Multilibs.select(D, Flags, Result.SelectedMultilibs))
|
||||
return;
|
||||
D.Diag(clang::diag::warn_drv_missing_multilib) << llvm::join(Flags, " ");
|
||||
std::stringstream ss;
|
||||
for (const Multilib &Multilib : Result.Multilibs)
|
||||
ss << "\n" << llvm::join(Multilib.flags(), " ");
|
||||
if (!Multilib.isFatalError())
|
||||
ss << "\n" << llvm::join(Multilib.flags(), " ");
|
||||
D.Diag(clang::diag::note_drv_available_multilibs) << ss.str();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -324,7 +324,7 @@ Fuchsia::Fuchsia(const Driver &D, const llvm::Triple &Triple,
|
|||
|
||||
Multilibs.setFilePathsCallback(FilePaths);
|
||||
|
||||
if (Multilibs.select(Flags, SelectedMultilibs)) {
|
||||
if (Multilibs.select(D, Flags, SelectedMultilibs)) {
|
||||
// Ensure that -print-multi-directory only outputs one multilib directory.
|
||||
Multilib LastSelected = SelectedMultilibs.back();
|
||||
SelectedMultilibs = {LastSelected};
|
||||
|
|
|
|||
|
|
@ -1041,7 +1041,8 @@ static bool isMSP430(llvm::Triple::ArchType Arch) {
|
|||
return Arch == llvm::Triple::msp430;
|
||||
}
|
||||
|
||||
static bool findMipsCsMultilibs(const Multilib::flags_list &Flags,
|
||||
static bool findMipsCsMultilibs(const Driver &D,
|
||||
const Multilib::flags_list &Flags,
|
||||
FilterNonExistent &NonExistent,
|
||||
DetectedMultilibs &Result) {
|
||||
// Check for Code Sourcery toolchain multilibs
|
||||
|
|
@ -1135,7 +1136,7 @@ static bool findMipsCsMultilibs(const Multilib::flags_list &Flags,
|
|||
if (CSMipsMultilibs.size() < DebianMipsMultilibs.size())
|
||||
std::iter_swap(Candidates, Candidates + 1);
|
||||
for (const MultilibSet *Candidate : Candidates) {
|
||||
if (Candidate->select(Flags, Result.SelectedMultilibs)) {
|
||||
if (Candidate->select(D, Flags, Result.SelectedMultilibs)) {
|
||||
if (Candidate == &DebianMipsMultilibs)
|
||||
Result.BiarchSibling = Multilib();
|
||||
Result.Multilibs = *Candidate;
|
||||
|
|
@ -1145,7 +1146,8 @@ static bool findMipsCsMultilibs(const Multilib::flags_list &Flags,
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool findMipsAndroidMultilibs(llvm::vfs::FileSystem &VFS, StringRef Path,
|
||||
static bool findMipsAndroidMultilibs(const Driver &D,
|
||||
llvm::vfs::FileSystem &VFS, StringRef Path,
|
||||
const Multilib::flags_list &Flags,
|
||||
FilterNonExistent &NonExistent,
|
||||
DetectedMultilibs &Result) {
|
||||
|
|
@ -1184,14 +1186,15 @@ static bool findMipsAndroidMultilibs(llvm::vfs::FileSystem &VFS, StringRef Path,
|
|||
MS = &AndroidMipselMultilibs;
|
||||
else if (VFS.exists(Path + "/32"))
|
||||
MS = &AndroidMips64elMultilibs;
|
||||
if (MS->select(Flags, Result.SelectedMultilibs)) {
|
||||
if (MS->select(D, Flags, Result.SelectedMultilibs)) {
|
||||
Result.Multilibs = *MS;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool findMipsMuslMultilibs(const Multilib::flags_list &Flags,
|
||||
static bool findMipsMuslMultilibs(const Driver &D,
|
||||
const Multilib::flags_list &Flags,
|
||||
FilterNonExistent &NonExistent,
|
||||
DetectedMultilibs &Result) {
|
||||
// Musl toolchain multilibs
|
||||
|
|
@ -1218,14 +1221,15 @@ static bool findMipsMuslMultilibs(const Multilib::flags_list &Flags,
|
|||
{"/../sysroot" + M.osSuffix() + "/usr/include"});
|
||||
});
|
||||
}
|
||||
if (MuslMipsMultilibs.select(Flags, Result.SelectedMultilibs)) {
|
||||
if (MuslMipsMultilibs.select(D, Flags, Result.SelectedMultilibs)) {
|
||||
Result.Multilibs = MuslMipsMultilibs;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool findMipsMtiMultilibs(const Multilib::flags_list &Flags,
|
||||
static bool findMipsMtiMultilibs(const Driver &D,
|
||||
const Multilib::flags_list &Flags,
|
||||
FilterNonExistent &NonExistent,
|
||||
DetectedMultilibs &Result) {
|
||||
// CodeScape MTI toolchain v1.2 and early.
|
||||
|
|
@ -1403,7 +1407,7 @@ static bool findMipsMtiMultilibs(const Multilib::flags_list &Flags,
|
|||
});
|
||||
}
|
||||
for (auto *Candidate : {&MtiMipsMultilibsV1, &MtiMipsMultilibsV2}) {
|
||||
if (Candidate->select(Flags, Result.SelectedMultilibs)) {
|
||||
if (Candidate->select(D, Flags, Result.SelectedMultilibs)) {
|
||||
Result.Multilibs = *Candidate;
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1411,7 +1415,8 @@ static bool findMipsMtiMultilibs(const Multilib::flags_list &Flags,
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool findMipsImgMultilibs(const Multilib::flags_list &Flags,
|
||||
static bool findMipsImgMultilibs(const Driver &D,
|
||||
const Multilib::flags_list &Flags,
|
||||
FilterNonExistent &NonExistent,
|
||||
DetectedMultilibs &Result) {
|
||||
// CodeScape IMG toolchain v1.2 and early.
|
||||
|
|
@ -1509,7 +1514,7 @@ static bool findMipsImgMultilibs(const Multilib::flags_list &Flags,
|
|||
});
|
||||
}
|
||||
for (auto *Candidate : {&ImgMultilibsV1, &ImgMultilibsV2}) {
|
||||
if (Candidate->select(Flags, Result.SelectedMultilibs)) {
|
||||
if (Candidate->select(D, Flags, Result.SelectedMultilibs)) {
|
||||
Result.Multilibs = *Candidate;
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1556,25 +1561,25 @@ bool clang::driver::findMIPSMultilibs(const Driver &D,
|
|||
addMultilibFlag(!isMipsEL(TargetArch), "-EB", Flags);
|
||||
|
||||
if (TargetTriple.isAndroid())
|
||||
return findMipsAndroidMultilibs(D.getVFS(), Path, Flags, NonExistent,
|
||||
return findMipsAndroidMultilibs(D, D.getVFS(), Path, Flags, NonExistent,
|
||||
Result);
|
||||
|
||||
if (TargetTriple.getVendor() == llvm::Triple::MipsTechnologies &&
|
||||
TargetTriple.getOS() == llvm::Triple::Linux &&
|
||||
TargetTriple.getEnvironment() == llvm::Triple::UnknownEnvironment)
|
||||
return findMipsMuslMultilibs(Flags, NonExistent, Result);
|
||||
return findMipsMuslMultilibs(D, Flags, NonExistent, Result);
|
||||
|
||||
if (TargetTriple.getVendor() == llvm::Triple::MipsTechnologies &&
|
||||
TargetTriple.getOS() == llvm::Triple::Linux &&
|
||||
TargetTriple.isGNUEnvironment())
|
||||
return findMipsMtiMultilibs(Flags, NonExistent, Result);
|
||||
return findMipsMtiMultilibs(D, Flags, NonExistent, Result);
|
||||
|
||||
if (TargetTriple.getVendor() == llvm::Triple::ImaginationTechnologies &&
|
||||
TargetTriple.getOS() == llvm::Triple::Linux &&
|
||||
TargetTriple.isGNUEnvironment())
|
||||
return findMipsImgMultilibs(Flags, NonExistent, Result);
|
||||
return findMipsImgMultilibs(D, Flags, NonExistent, Result);
|
||||
|
||||
if (findMipsCsMultilibs(Flags, NonExistent, Result))
|
||||
if (findMipsCsMultilibs(D, Flags, NonExistent, Result))
|
||||
return true;
|
||||
|
||||
// Fallback to the regular toolchain-tree structure.
|
||||
|
|
@ -1582,7 +1587,7 @@ bool clang::driver::findMIPSMultilibs(const Driver &D,
|
|||
Result.Multilibs.push_back(Default);
|
||||
Result.Multilibs.FilterOut(NonExistent);
|
||||
|
||||
if (Result.Multilibs.select(Flags, Result.SelectedMultilibs)) {
|
||||
if (Result.Multilibs.select(D, Flags, Result.SelectedMultilibs)) {
|
||||
Result.BiarchSibling = Multilib();
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1629,7 +1634,7 @@ static void findAndroidArmMultilibs(const Driver &D,
|
|||
addMultilibFlag(IsArmV7Mode, "-march=armv7-a", Flags);
|
||||
addMultilibFlag(IsThumbMode, "-mthumb", Flags);
|
||||
|
||||
if (AndroidArmMultilibs.select(Flags, Result.SelectedMultilibs))
|
||||
if (AndroidArmMultilibs.select(D, Flags, Result.SelectedMultilibs))
|
||||
Result.Multilibs = AndroidArmMultilibs;
|
||||
}
|
||||
|
||||
|
|
@ -1655,7 +1660,7 @@ static bool findMSP430Multilibs(const Driver &D,
|
|||
addMultilibFlag(Args.hasFlag(options::OPT_fexceptions,
|
||||
options::OPT_fno_exceptions, false),
|
||||
"-exceptions", Flags);
|
||||
if (Result.Multilibs.select(Flags, Result.SelectedMultilibs))
|
||||
if (Result.Multilibs.select(D, Flags, Result.SelectedMultilibs))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
|
@ -1722,7 +1727,7 @@ static void findCSKYMultilibs(const Driver &D, const llvm::Triple &TargetTriple,
|
|||
.makeMultilibSet()
|
||||
.FilterOut(NonExistent);
|
||||
|
||||
if (CSKYMultilibs.select(Flags, Result.SelectedMultilibs))
|
||||
if (CSKYMultilibs.select(D, Flags, Result.SelectedMultilibs))
|
||||
Result.Multilibs = CSKYMultilibs;
|
||||
}
|
||||
|
||||
|
|
@ -1737,11 +1742,11 @@ static void findCSKYMultilibs(const Driver &D, const llvm::Triple &TargetTriple,
|
|||
/// march=rv32ima are not compatible, because software and hardware
|
||||
/// atomic operation can't work together correctly.
|
||||
static bool
|
||||
selectRISCVMultilib(const MultilibSet &RISCVMultilibSet, StringRef Arch,
|
||||
const Multilib::flags_list &Flags,
|
||||
selectRISCVMultilib(const Driver &D, const MultilibSet &RISCVMultilibSet,
|
||||
StringRef Arch, const Multilib::flags_list &Flags,
|
||||
llvm::SmallVectorImpl<Multilib> &SelectedMultilibs) {
|
||||
// Try to find the perfect matching multi-lib first.
|
||||
if (RISCVMultilibSet.select(Flags, SelectedMultilibs))
|
||||
if (RISCVMultilibSet.select(D, Flags, SelectedMultilibs))
|
||||
return true;
|
||||
|
||||
Multilib::flags_list NewFlags;
|
||||
|
|
@ -1833,7 +1838,7 @@ selectRISCVMultilib(const MultilibSet &RISCVMultilibSet, StringRef Arch,
|
|||
MultilibSet NewRISCVMultilibs =
|
||||
MultilibSetBuilder().Either(NewMultilibs).makeMultilibSet();
|
||||
|
||||
if (NewRISCVMultilibs.select(NewFlags, SelectedMultilibs))
|
||||
if (NewRISCVMultilibs.select(D, NewFlags, SelectedMultilibs))
|
||||
for (const Multilib &NewSelectedM : SelectedMultilibs)
|
||||
for (const auto &M : RISCVMultilibSet)
|
||||
// Look up the corresponding multi-lib entry in original multi-lib set.
|
||||
|
|
@ -1894,7 +1899,7 @@ static void findRISCVBareMetalMultilibs(const Driver &D,
|
|||
}
|
||||
}
|
||||
|
||||
if (selectRISCVMultilib(RISCVMultilibs, MArch, Flags,
|
||||
if (selectRISCVMultilib(D, RISCVMultilibs, MArch, Flags,
|
||||
Result.SelectedMultilibs))
|
||||
Result.Multilibs = RISCVMultilibs;
|
||||
}
|
||||
|
|
@ -1937,7 +1942,7 @@ static void findRISCVMultilibs(const Driver &D,
|
|||
addMultilibFlag(ABIName == "lp64f", "-mabi=lp64f", Flags);
|
||||
addMultilibFlag(ABIName == "lp64d", "-mabi=lp64d", Flags);
|
||||
|
||||
if (RISCVMultilibs.select(Flags, Result.SelectedMultilibs))
|
||||
if (RISCVMultilibs.select(D, Flags, Result.SelectedMultilibs))
|
||||
Result.Multilibs = RISCVMultilibs;
|
||||
}
|
||||
|
||||
|
|
@ -2057,7 +2062,7 @@ static bool findBiarchMultilibs(const Driver &D,
|
|||
addMultilibFlag(TargetTriple.isArch32Bit(), "-m32", Flags);
|
||||
addMultilibFlag(TargetTriple.isArch64Bit() && IsX32, "-mx32", Flags);
|
||||
|
||||
if (!Result.Multilibs.select(Flags, Result.SelectedMultilibs))
|
||||
if (!Result.Multilibs.select(D, Flags, Result.SelectedMultilibs))
|
||||
return false;
|
||||
|
||||
if (Result.SelectedMultilibs.back() == Alt64 ||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,8 @@ using namespace clang::driver::tools::arm;
|
|||
using tools::addMultilibFlag;
|
||||
using tools::addPathIfExists;
|
||||
|
||||
static bool findOHOSMuslMultilibs(const Multilib::flags_list &Flags,
|
||||
static bool findOHOSMuslMultilibs(const Driver &D,
|
||||
const Multilib::flags_list &Flags,
|
||||
DetectedMultilibs &Result) {
|
||||
MultilibSet Multilibs;
|
||||
Multilibs.push_back(Multilib());
|
||||
|
|
@ -50,7 +51,7 @@ static bool findOHOSMuslMultilibs(const Multilib::flags_list &Flags,
|
|||
Multilib("/a7_hard_neon-vfpv4", {}, {},
|
||||
{"-mcpu=cortex-a7", "-mfloat-abi=hard", "-mfpu=neon-vfpv4"}));
|
||||
|
||||
if (Multilibs.select(Flags, Result.SelectedMultilibs)) {
|
||||
if (Multilibs.select(D, Flags, Result.SelectedMultilibs)) {
|
||||
Result.Multilibs = Multilibs;
|
||||
return true;
|
||||
}
|
||||
|
|
@ -81,7 +82,7 @@ static bool findOHOSMultilibs(const Driver &D,
|
|||
addMultilibFlag((ARMFloatABI == tools::arm::FloatABI::Hard),
|
||||
"-mfloat-abi=hard", Flags);
|
||||
|
||||
return findOHOSMuslMultilibs(Flags, Result);
|
||||
return findOHOSMuslMultilibs(D, Flags, Result);
|
||||
}
|
||||
|
||||
std::string OHOS::getMultiarchTriple(const llvm::Triple &T) const {
|
||||
|
|
|
|||
63
clang/test/Driver/baremetal-multilib-custom-error.yaml
Normal file
63
clang/test/Driver/baremetal-multilib-custom-error.yaml
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
# REQUIRES: shell
|
||||
# UNSUPPORTED: system-windows
|
||||
|
||||
# RUN: rm -rf %t
|
||||
# RUN: mkdir -p %t/bin
|
||||
# RUN: mkdir -p %t/lib/clang-runtimes/arm-none-eabi/thumb/v8-m.main/fp/lib
|
||||
# RUN: touch %t/lib/clang-runtimes/arm-none-eabi/thumb/v8-m.main/fp/lib/libclang_rt.builtins.a
|
||||
# RUN: ln -s %clang %t/bin/clang
|
||||
# RUN: ln -s %s %t/lib/clang-runtimes/multilib.yaml
|
||||
|
||||
# RUN: %t/bin/clang -no-canonical-prefixes -print-multi-directory 2>&1 \
|
||||
# RUN: --target=thumbv8m.main-none-eabi -march=armv8.1m.main --sysroot= \
|
||||
# RUN: | FileCheck --check-prefix=CHECK-PRINT-MULTI-DIRECTORY-NOMVE-SOFTFLOAT %s
|
||||
# CHECK-PRINT-MULTI-DIRECTORY-NOMVE-SOFTFLOAT: nomve-softfloat
|
||||
|
||||
# RUN: not %t/bin/clang -no-canonical-prefixes -print-multi-directory 2>&1 \
|
||||
# RUN: --target=thumbv8m.main-none-eabi -march=armv8.1m.main+mve --sysroot= \
|
||||
# RUN: | FileCheck --check-prefix=CHECK-ERROR %s
|
||||
# CHECK-ERROR: multilib configuration error: mve-softfloat is not supported
|
||||
|
||||
# RUN: %t/bin/clang -no-canonical-prefixes -print-multi-directory 2>&1 \
|
||||
# RUN: --target=thumbv8m.main-none-eabi -march=armv8.1m.main+mve -mfloat-abi=hard --sysroot= \
|
||||
# RUN: | FileCheck --check-prefix=CHECK-PRINT-MULTI-DIRECTORY-MVE-HARDFLOAT %s
|
||||
# CHECK-PRINT-MULTI-DIRECTORY-MVE-HARDFLOAT: mve-hardfloat
|
||||
|
||||
# RUN: %t/bin/clang -no-canonical-prefixes -print-multi-lib 2>&1 \
|
||||
# RUN: --target=arm-none-eabi --sysroot= \
|
||||
# RUN: | FileCheck --check-prefix=CHECK-PRINT-MULTI-LIB %s
|
||||
# CHECK-PRINT-MULTI-LIB: nomve-softfloat;@-target=thumbv8.1m.main-unknown-none-eabi
|
||||
# CHECK-PRINT-MULTI-LIB-NEXT: mve-hardfloat;@-target=thumbv8.1m.main-unknown-none-eabihf@march=thumbv8.1m.main+mve@mfloat-abi=hard
|
||||
|
||||
# RUN: %t/bin/clang -no-canonical-prefixes -print-multi-directory 2>&1 \
|
||||
# RUN: --target=arm-none-eabi --sysroot= \
|
||||
# RUN: | FileCheck --check-prefix=CHECK-NO-MATCH-WARNING %s
|
||||
# CHECK-NO-MATCH-WARNING: clang: note: available multilibs are:
|
||||
# CHECK-NO-MATCH-WARNING-NEXT: --target=thumbv8.1m.main-unknown-none-eabi
|
||||
# CHECK-NO-MATCH-WARNING-NEXT: --target=thumbv8.1m.main-unknown-none-eabihf -march=thumbv8.1m.main+mve -mfloat-abi=hard
|
||||
|
||||
---
|
||||
MultilibVersion: 1.0
|
||||
|
||||
Variants:
|
||||
- Dir: nomve-softfloat
|
||||
Flags:
|
||||
- --target=thumbv8.1m.main-unknown-none-eabi
|
||||
|
||||
- FatalError: mve-softfloat is not supported
|
||||
Flags:
|
||||
- --target=thumbv8.1m.main-unknown-none-eabi
|
||||
- -march=thumbv8.1m.main+mve
|
||||
|
||||
- Dir: mve-hardfloat
|
||||
Flags:
|
||||
- --target=thumbv8.1m.main-unknown-none-eabihf
|
||||
- -march=thumbv8.1m.main+mve
|
||||
- -mfloat-abi=hard
|
||||
|
||||
Mappings:
|
||||
- Match: -march=thumbv8\.1m\.main(\+[^\+]+)*\+mve(\+[^\+]+)*
|
||||
Flags:
|
||||
- -march=thumbv8.1m.main+mve
|
||||
|
||||
...
|
||||
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include "clang/Driver/MultilibBuilder.h"
|
||||
#include "../../lib/Driver/ToolChains/CommonArgs.h"
|
||||
#include "SimpleDiagnosticConsumer.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
|
|
@ -164,7 +165,8 @@ TEST(MultilibBuilderTest, SetSelection1) {
|
|||
|
||||
Multilib::flags_list FlagM64 = {"-m64"};
|
||||
llvm::SmallVector<Multilib> SelectionM64;
|
||||
ASSERT_TRUE(MS1.select(FlagM64, SelectionM64))
|
||||
Driver TheDriver = diagnostic_test_driver();
|
||||
ASSERT_TRUE(MS1.select(TheDriver, FlagM64, SelectionM64))
|
||||
<< "Flag set was {\"-m64\"}, but selection not found";
|
||||
ASSERT_TRUE(SelectionM64.back().gccSuffix() == "/64")
|
||||
<< "Selection picked " << SelectionM64.back()
|
||||
|
|
@ -172,7 +174,7 @@ TEST(MultilibBuilderTest, SetSelection1) {
|
|||
|
||||
Multilib::flags_list FlagNoM64 = {"!m64"};
|
||||
llvm::SmallVector<Multilib> SelectionNoM64;
|
||||
ASSERT_TRUE(MS1.select(FlagNoM64, SelectionNoM64))
|
||||
ASSERT_TRUE(MS1.select(TheDriver, FlagNoM64, SelectionNoM64))
|
||||
<< "Flag set was {\"!m64\"}, but selection not found";
|
||||
ASSERT_TRUE(SelectionNoM64.back().gccSuffix() == "")
|
||||
<< "Selection picked " << SelectionNoM64.back()
|
||||
|
|
@ -200,7 +202,8 @@ TEST(MultilibBuilderTest, SetSelection2) {
|
|||
Flags.push_back("!SF");
|
||||
|
||||
llvm::SmallVector<Multilib> Selection;
|
||||
ASSERT_TRUE(MS2.select(Flags, Selection))
|
||||
Driver TheDriver = diagnostic_test_driver();
|
||||
ASSERT_TRUE(MS2.select(TheDriver, Flags, Selection))
|
||||
<< "Selection failed for " << (IsEL ? "-EL" : "!EL") << " "
|
||||
<< (IsSF ? "-SF" : "!SF");
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include "clang/Driver/Multilib.h"
|
||||
#include "../../lib/Driver/ToolChains/CommonArgs.h"
|
||||
#include "SimpleDiagnosticConsumer.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "clang/Basic/Version.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
|
|
@ -153,16 +154,17 @@ TEST(MultilibTest, SetPriority) {
|
|||
Multilib("/foo", {}, {}, {"+foo"}),
|
||||
Multilib("/bar", {}, {}, {"+bar"}),
|
||||
});
|
||||
Driver TheDriver = diagnostic_test_driver();
|
||||
Multilib::flags_list Flags1 = {"+foo", "-bar"};
|
||||
llvm::SmallVector<Multilib> Selection1;
|
||||
ASSERT_TRUE(MS.select(Flags1, Selection1))
|
||||
ASSERT_TRUE(MS.select(TheDriver, Flags1, Selection1))
|
||||
<< "Flag set was {\"+foo\"}, but selection not found";
|
||||
ASSERT_TRUE(Selection1.back().gccSuffix() == "/foo")
|
||||
<< "Selection picked " << Selection1.back() << " which was not expected";
|
||||
|
||||
Multilib::flags_list Flags2 = {"+foo", "+bar"};
|
||||
llvm::SmallVector<Multilib> Selection2;
|
||||
ASSERT_TRUE(MS.select(Flags2, Selection2))
|
||||
ASSERT_TRUE(MS.select(TheDriver, Flags2, Selection2))
|
||||
<< "Flag set was {\"+bar\"}, but selection not found";
|
||||
ASSERT_TRUE(Selection2.back().gccSuffix() == "/bar")
|
||||
<< "Selection picked " << Selection2.back() << " which was not expected";
|
||||
|
|
@ -174,16 +176,17 @@ TEST(MultilibTest, SelectMultiple) {
|
|||
Multilib("/b", {}, {}, {"y"}),
|
||||
});
|
||||
llvm::SmallVector<Multilib> Selection;
|
||||
Driver TheDriver = diagnostic_test_driver();
|
||||
|
||||
ASSERT_TRUE(MS.select({"x"}, Selection));
|
||||
ASSERT_TRUE(MS.select(TheDriver, {"x"}, Selection));
|
||||
ASSERT_EQ(1u, Selection.size());
|
||||
EXPECT_EQ("/a", Selection[0].gccSuffix());
|
||||
|
||||
ASSERT_TRUE(MS.select({"y"}, Selection));
|
||||
ASSERT_TRUE(MS.select(TheDriver, {"y"}, Selection));
|
||||
ASSERT_EQ(1u, Selection.size());
|
||||
EXPECT_EQ("/b", Selection[0].gccSuffix());
|
||||
|
||||
ASSERT_TRUE(MS.select({"y", "x"}, Selection));
|
||||
ASSERT_TRUE(MS.select(TheDriver, {"y", "x"}, Selection));
|
||||
ASSERT_EQ(2u, Selection.size());
|
||||
EXPECT_EQ("/a", Selection[0].gccSuffix());
|
||||
EXPECT_EQ("/b", Selection[1].gccSuffix());
|
||||
|
|
@ -277,7 +280,9 @@ Variants:
|
|||
Variants:
|
||||
- Flags: []
|
||||
)"));
|
||||
EXPECT_TRUE(StringRef(Diagnostic).contains("missing required key 'Dir'"))
|
||||
EXPECT_TRUE(
|
||||
StringRef(Diagnostic)
|
||||
.contains("one of the 'Dir' and 'FatalError' keys must be specified"))
|
||||
<< Diagnostic;
|
||||
|
||||
EXPECT_FALSE(parseYaml(MS, Diagnostic, YAML_PREAMBLE R"(
|
||||
|
|
@ -364,9 +369,10 @@ Mappings:
|
|||
- Match: -mfloat-abi=softfp
|
||||
Flags: [-mfloat-abi=soft]
|
||||
)"));
|
||||
EXPECT_TRUE(MS.select({"-mfloat-abi=soft"}, Selected));
|
||||
EXPECT_TRUE(MS.select({"-mfloat-abi=softfp"}, Selected));
|
||||
EXPECT_FALSE(MS.select({"-mfloat-abi=hard"}, Selected));
|
||||
Driver TheDriver = diagnostic_test_driver();
|
||||
EXPECT_TRUE(MS.select(TheDriver, {"-mfloat-abi=soft"}, Selected));
|
||||
EXPECT_TRUE(MS.select(TheDriver, {"-mfloat-abi=softfp"}, Selected));
|
||||
EXPECT_FALSE(MS.select(TheDriver, {"-mfloat-abi=hard"}, Selected));
|
||||
}
|
||||
|
||||
TEST(MultilibTest, SelectSoftFP) {
|
||||
|
|
@ -377,9 +383,10 @@ Variants:
|
|||
- Dir: f
|
||||
Flags: [-mfloat-abi=softfp]
|
||||
)"));
|
||||
EXPECT_FALSE(MS.select({"-mfloat-abi=soft"}, Selected));
|
||||
EXPECT_TRUE(MS.select({"-mfloat-abi=softfp"}, Selected));
|
||||
EXPECT_FALSE(MS.select({"-mfloat-abi=hard"}, Selected));
|
||||
Driver TheDriver = diagnostic_test_driver();
|
||||
EXPECT_FALSE(MS.select(TheDriver, {"-mfloat-abi=soft"}, Selected));
|
||||
EXPECT_TRUE(MS.select(TheDriver, {"-mfloat-abi=softfp"}, Selected));
|
||||
EXPECT_FALSE(MS.select(TheDriver, {"-mfloat-abi=hard"}, Selected));
|
||||
}
|
||||
|
||||
TEST(MultilibTest, SelectHard) {
|
||||
|
|
@ -392,9 +399,10 @@ Variants:
|
|||
- Dir: h
|
||||
Flags: [-mfloat-abi=hard]
|
||||
)"));
|
||||
EXPECT_FALSE(MS.select({"-mfloat-abi=soft"}, Selected));
|
||||
EXPECT_FALSE(MS.select({"-mfloat-abi=softfp"}, Selected));
|
||||
EXPECT_TRUE(MS.select({"-mfloat-abi=hard"}, Selected));
|
||||
Driver TheDriver = diagnostic_test_driver();
|
||||
EXPECT_FALSE(MS.select(TheDriver, {"-mfloat-abi=soft"}, Selected));
|
||||
EXPECT_FALSE(MS.select(TheDriver, {"-mfloat-abi=softfp"}, Selected));
|
||||
EXPECT_TRUE(MS.select(TheDriver, {"-mfloat-abi=hard"}, Selected));
|
||||
}
|
||||
|
||||
TEST(MultilibTest, SelectFloatABI) {
|
||||
|
|
@ -412,11 +420,12 @@ Mappings:
|
|||
- Match: -mfloat-abi=softfp
|
||||
Flags: [-mfloat-abi=soft]
|
||||
)"));
|
||||
MS.select({"-mfloat-abi=soft"}, Selected);
|
||||
Driver TheDriver = diagnostic_test_driver();
|
||||
MS.select(TheDriver, {"-mfloat-abi=soft"}, Selected);
|
||||
EXPECT_EQ("/s", Selected.back().gccSuffix());
|
||||
MS.select({"-mfloat-abi=softfp"}, Selected);
|
||||
MS.select(TheDriver, {"-mfloat-abi=softfp"}, Selected);
|
||||
EXPECT_EQ("/f", Selected.back().gccSuffix());
|
||||
MS.select({"-mfloat-abi=hard"}, Selected);
|
||||
MS.select(TheDriver, {"-mfloat-abi=hard"}, Selected);
|
||||
EXPECT_EQ("/h", Selected.back().gccSuffix());
|
||||
}
|
||||
|
||||
|
|
@ -437,15 +446,18 @@ Mappings:
|
|||
- Match: -mfloat-abi=softfp
|
||||
Flags: [-mfloat-abi=soft]
|
||||
)"));
|
||||
MS.select({"-mfloat-abi=soft"}, Selected);
|
||||
Driver TheDriver = diagnostic_test_driver();
|
||||
MS.select(TheDriver, {"-mfloat-abi=soft"}, Selected);
|
||||
EXPECT_EQ("/s", Selected.back().gccSuffix());
|
||||
MS.select({"-mfloat-abi=softfp"}, Selected);
|
||||
MS.select(TheDriver, {"-mfloat-abi=softfp"}, Selected);
|
||||
EXPECT_EQ("/s", Selected.back().gccSuffix());
|
||||
MS.select({"-mfloat-abi=hard"}, Selected);
|
||||
MS.select(TheDriver, {"-mfloat-abi=hard"}, Selected);
|
||||
EXPECT_EQ("/h", Selected.back().gccSuffix());
|
||||
}
|
||||
|
||||
TEST(MultilibTest, SelectMClass) {
|
||||
Driver TheDriver = diagnostic_test_driver();
|
||||
|
||||
const char *MultilibSpec = YAML_PREAMBLE R"(
|
||||
Variants:
|
||||
- Dir: thumb/v6-m/nofp
|
||||
|
|
@ -493,44 +505,52 @@ Mappings:
|
|||
llvm::SmallVector<Multilib> Selected;
|
||||
ASSERT_TRUE(parseYaml(MS, MultilibSpec));
|
||||
|
||||
ASSERT_TRUE(MS.select({"--target=thumbv6m-none-unknown-eabi", "-mfpu=none"},
|
||||
ASSERT_TRUE(MS.select(TheDriver,
|
||||
{"--target=thumbv6m-none-unknown-eabi", "-mfpu=none"},
|
||||
Selected));
|
||||
EXPECT_EQ("/thumb/v6-m/nofp", Selected.back().gccSuffix());
|
||||
|
||||
ASSERT_TRUE(MS.select({"--target=thumbv7m-none-unknown-eabi", "-mfpu=none"},
|
||||
ASSERT_TRUE(MS.select(TheDriver,
|
||||
{"--target=thumbv7m-none-unknown-eabi", "-mfpu=none"},
|
||||
Selected));
|
||||
EXPECT_EQ("/thumb/v7-m/nofp", Selected.back().gccSuffix());
|
||||
|
||||
ASSERT_TRUE(MS.select({"--target=thumbv7em-none-unknown-eabi", "-mfpu=none"},
|
||||
ASSERT_TRUE(MS.select(TheDriver,
|
||||
{"--target=thumbv7em-none-unknown-eabi", "-mfpu=none"},
|
||||
Selected));
|
||||
EXPECT_EQ("/thumb/v7e-m/nofp", Selected.back().gccSuffix());
|
||||
|
||||
ASSERT_TRUE(MS.select(
|
||||
{"--target=thumbv8m.main-none-unknown-eabi", "-mfpu=none"}, Selected));
|
||||
TheDriver, {"--target=thumbv8m.main-none-unknown-eabi", "-mfpu=none"},
|
||||
Selected));
|
||||
EXPECT_EQ("/thumb/v8-m.main/nofp", Selected.back().gccSuffix());
|
||||
|
||||
ASSERT_TRUE(MS.select(
|
||||
{"--target=thumbv8.1m.main-none-unknown-eabi", "-mfpu=none"}, Selected));
|
||||
TheDriver, {"--target=thumbv8.1m.main-none-unknown-eabi", "-mfpu=none"},
|
||||
Selected));
|
||||
EXPECT_EQ("/thumb/v8.1-m.main/nofp/nomve", Selected.back().gccSuffix());
|
||||
|
||||
ASSERT_TRUE(
|
||||
MS.select({"--target=thumbv7em-none-unknown-eabihf", "-mfpu=fpv4-sp-d16"},
|
||||
MS.select(TheDriver,
|
||||
{"--target=thumbv7em-none-unknown-eabihf", "-mfpu=fpv4-sp-d16"},
|
||||
Selected));
|
||||
EXPECT_EQ("/thumb/v7e-m/fpv4_sp_d16", Selected.back().gccSuffix());
|
||||
|
||||
ASSERT_TRUE(MS.select(
|
||||
{"--target=thumbv7em-none-unknown-eabihf", "-mfpu=fpv5-d16"}, Selected));
|
||||
TheDriver, {"--target=thumbv7em-none-unknown-eabihf", "-mfpu=fpv5-d16"},
|
||||
Selected));
|
||||
EXPECT_EQ("/thumb/v7e-m/fpv5_d16", Selected.back().gccSuffix());
|
||||
|
||||
ASSERT_TRUE(
|
||||
MS.select({"--target=thumbv8m.main-none-unknown-eabihf"}, Selected));
|
||||
ASSERT_TRUE(MS.select(
|
||||
TheDriver, {"--target=thumbv8m.main-none-unknown-eabihf"}, Selected));
|
||||
EXPECT_EQ("/thumb/v8-m.main/fp", Selected.back().gccSuffix());
|
||||
|
||||
ASSERT_TRUE(
|
||||
MS.select({"--target=thumbv8.1m.main-none-unknown-eabihf"}, Selected));
|
||||
ASSERT_TRUE(MS.select(
|
||||
TheDriver, {"--target=thumbv8.1m.main-none-unknown-eabihf"}, Selected));
|
||||
EXPECT_EQ("/thumb/v8.1-m.main/fp", Selected.back().gccSuffix());
|
||||
|
||||
ASSERT_TRUE(MS.select({"--target=thumbv8.1m.main-none-unknown-eabihf",
|
||||
ASSERT_TRUE(MS.select(TheDriver,
|
||||
{"--target=thumbv8.1m.main-none-unknown-eabihf",
|
||||
"-mfpu=none", "-march=thumbv8.1m.main+dsp+mve"},
|
||||
Selected));
|
||||
EXPECT_EQ("/thumb/v8.1-m.main/nofp/mve", Selected.back().gccSuffix());
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/Support/VirtualFileSystem.h"
|
||||
|
||||
struct SimpleDiagnosticConsumer : public clang::DiagnosticConsumer {
|
||||
void HandleDiagnostic(clang::DiagnosticsEngine::Level DiagLevel,
|
||||
|
|
@ -36,4 +37,19 @@ struct SimpleDiagnosticConsumer : public clang::DiagnosticConsumer {
|
|||
std::vector<llvm::SmallString<32>> Errors;
|
||||
};
|
||||
|
||||
// Using SimpleDiagnosticConsumer, this function makes a clang Driver, suitable
|
||||
// for testing situations where it will only ever be used for emitting
|
||||
// diagnostics, such as being passed to `MultilibSet::select`.
|
||||
inline clang::driver::Driver diagnostic_test_driver() {
|
||||
llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagID(
|
||||
new clang::DiagnosticIDs());
|
||||
llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
|
||||
new llvm::vfs::InMemoryFileSystem);
|
||||
auto *DiagConsumer = new SimpleDiagnosticConsumer;
|
||||
llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> DiagOpts =
|
||||
new clang::DiagnosticOptions();
|
||||
clang::DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagConsumer);
|
||||
return clang::driver::Driver("/bin/clang", "", Diags, "", InMemoryFileSystem);
|
||||
}
|
||||
|
||||
#endif // CLANG_UNITTESTS_SIMPLEDIAGNOSTICCONSUMER_H
|
||||
|
|
|
|||
Loading…
Reference in a new issue