зеркало из https://github.com/microsoft/clang.git
Revert 201202
Breaks cmake configure of new unit tests directory git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@201203 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
1b6afd89e6
Коммит
56c7cf67c6
|
@ -1,163 +0,0 @@
|
|||
//===--- Multilib.h ---------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef CLANG_LIB_DRIVER_MULTILIB_H_
|
||||
#define CLANG_LIB_DRIVER_MULTILIB_H_
|
||||
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/Option/Option.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace clang {
|
||||
namespace driver {
|
||||
|
||||
/// This corresponds to a single GCC Multilib, or a segment of one controlled
|
||||
/// by a command line flag
|
||||
class Multilib {
|
||||
public:
|
||||
typedef std::vector<std::string> flags_list;
|
||||
|
||||
private:
|
||||
std::string GCCSuffix;
|
||||
std::string OSSuffix;
|
||||
std::string IncludeSuffix;
|
||||
flags_list Flags;
|
||||
|
||||
public:
|
||||
Multilib(StringRef GCCSuffix = "", StringRef OSSuffix = "",
|
||||
StringRef IncludeSuffix = "");
|
||||
|
||||
/// \brief Get the detected GCC installation path suffix for the multi-arch
|
||||
/// target variant. Always starts with a '/', unless empty
|
||||
const std::string &gccSuffix() const {
|
||||
assert(GCCSuffix.empty() ||
|
||||
(StringRef(GCCSuffix).front() == '/' && GCCSuffix.size() > 1));
|
||||
return GCCSuffix;
|
||||
}
|
||||
/// Set the GCC installation path suffix.
|
||||
Multilib &gccSuffix(StringRef S);
|
||||
|
||||
/// \brief Get the detected os path suffix for the multi-arch
|
||||
/// target variant. Always starts with a '/', unless empty
|
||||
const std::string &osSuffix() const {
|
||||
assert(OSSuffix.empty() ||
|
||||
(StringRef(OSSuffix).front() == '/' && OSSuffix.size() > 1));
|
||||
return OSSuffix;
|
||||
}
|
||||
/// Set the os path suffix.
|
||||
Multilib &osSuffix(StringRef S);
|
||||
|
||||
/// \brief Get the include directory suffix. Always starts with a '/', unless
|
||||
/// empty
|
||||
const std::string &includeSuffix() const {
|
||||
assert(IncludeSuffix.empty() ||
|
||||
(StringRef(IncludeSuffix).front() == '/' && IncludeSuffix.size() > 1));
|
||||
return IncludeSuffix;
|
||||
}
|
||||
/// Set the include directory suffix
|
||||
Multilib &includeSuffix(StringRef S);
|
||||
|
||||
/// \brief Get the flags that indicate or contraindicate this multilib's use
|
||||
/// All elements begin with either '+' or '-'
|
||||
const flags_list &flags() const { return Flags; }
|
||||
flags_list &flags() { return Flags; }
|
||||
/// Add a flag to the flags list
|
||||
Multilib &flag(StringRef F) {
|
||||
assert(F.front() == '+' || F.front() == '-');
|
||||
Flags.push_back(F);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief print summary of the Multilib
|
||||
void print(raw_ostream &OS) const;
|
||||
|
||||
/// Check whether any of the 'against' flags contradict the 'for' flags.
|
||||
bool isValid() const;
|
||||
|
||||
bool operator==(const Multilib &Other) const;
|
||||
};
|
||||
|
||||
raw_ostream &operator<<(raw_ostream &OS, const Multilib &M);
|
||||
|
||||
class MultilibSet {
|
||||
public:
|
||||
typedef std::vector<Multilib> multilib_list;
|
||||
typedef multilib_list::iterator iterator;
|
||||
typedef multilib_list::const_iterator const_iterator;
|
||||
|
||||
struct FilterCallback {
|
||||
virtual ~FilterCallback() {};
|
||||
/// \return true iff the filter should remove the Multilib from the set
|
||||
virtual bool operator()(const Multilib &M) const = 0;
|
||||
};
|
||||
|
||||
private:
|
||||
multilib_list Multilibs;
|
||||
|
||||
public:
|
||||
MultilibSet() {}
|
||||
|
||||
/// Add an optional Multilib segment
|
||||
MultilibSet &Maybe(const Multilib &M);
|
||||
|
||||
/// Add a set of mutually incompatible Multilib segments
|
||||
MultilibSet &Either(const Multilib &M1, const Multilib &M2);
|
||||
MultilibSet &Either(const Multilib &M1, const Multilib &M2,
|
||||
const Multilib &M3);
|
||||
MultilibSet &Either(const Multilib &M1, const Multilib &M2,
|
||||
const Multilib &M3, const Multilib &M4);
|
||||
MultilibSet &Either(const Multilib &M1, const Multilib &M2,
|
||||
const Multilib &M3, const Multilib &M4,
|
||||
const Multilib &M5);
|
||||
MultilibSet &Either(const std::vector<Multilib> &Ms);
|
||||
|
||||
/// Filter out some subset of the Multilibs using a user defined callback
|
||||
MultilibSet &FilterOut(const FilterCallback &F);
|
||||
/// Filter out those Multilibs whose gccSuffix matches the given expression
|
||||
MultilibSet &FilterOut(std::string Regex);
|
||||
|
||||
/// Add a completed Multilib to the set
|
||||
void push_back(const Multilib &M);
|
||||
|
||||
/// Union this set of multilibs with another
|
||||
void combineWith(const MultilibSet &MS);
|
||||
|
||||
/// Remove all of thie multilibs from the set
|
||||
void clear() { Multilibs.clear(); }
|
||||
|
||||
iterator begin() { return Multilibs.begin(); }
|
||||
const_iterator begin() const { return Multilibs.begin(); }
|
||||
|
||||
iterator end() { return Multilibs.end(); }
|
||||
const_iterator end() const { return Multilibs.end(); }
|
||||
|
||||
/// Pick the best multilib in the set, \returns false if none are compatible
|
||||
bool select(const Multilib::flags_list &Flags, Multilib &M) const;
|
||||
|
||||
unsigned size() const { return Multilibs.size(); }
|
||||
|
||||
void print(raw_ostream &OS) const;
|
||||
|
||||
private:
|
||||
/// Apply the filter to Multilibs and return the subset that remains
|
||||
static multilib_list filterCopy(const FilterCallback &F,
|
||||
const multilib_list &Ms);
|
||||
|
||||
/// Apply the filter to the multilib_list, removing those that don't match
|
||||
static void filterInPlace(const FilterCallback &F, multilib_list &Ms);
|
||||
};
|
||||
|
||||
raw_ostream &operator<<(raw_ostream &OS, const MultilibSet &MS);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -11,7 +11,6 @@
|
|||
#define CLANG_DRIVER_TOOLCHAIN_H_
|
||||
|
||||
#include "clang/Driver/Action.h"
|
||||
#include "clang/Driver/Multilib.h"
|
||||
#include "clang/Driver/Types.h"
|
||||
#include "clang/Driver/Util.h"
|
||||
#include "llvm/ADT/OwningPtr.h"
|
||||
|
@ -77,8 +76,6 @@ private:
|
|||
mutable OwningPtr<SanitizerArgs> SanitizerArguments;
|
||||
|
||||
protected:
|
||||
MultilibSet Multilibs;
|
||||
|
||||
ToolChain(const Driver &D, const llvm::Triple &T,
|
||||
const llvm::opt::ArgList &Args);
|
||||
|
||||
|
@ -133,8 +130,6 @@ public:
|
|||
path_list &getProgramPaths() { return ProgramPaths; }
|
||||
const path_list &getProgramPaths() const { return ProgramPaths; }
|
||||
|
||||
const MultilibSet &getMultilibs() const { return Multilibs; }
|
||||
|
||||
const SanitizerArgs& getSanitizerArgs() const;
|
||||
|
||||
// Tool access.
|
||||
|
|
|
@ -11,7 +11,6 @@ add_clang_library(clangDriver
|
|||
Driver.cpp
|
||||
DriverOptions.cpp
|
||||
Job.cpp
|
||||
Multilib.cpp
|
||||
Phases.cpp
|
||||
SanitizerArgs.cpp
|
||||
Tool.cpp
|
||||
|
|
|
@ -748,34 +748,51 @@ bool Driver::HandleImmediateArgs(const Compilation &C) {
|
|||
}
|
||||
|
||||
if (C.getArgs().hasArg(options::OPT_print_multi_lib)) {
|
||||
const MultilibSet &Multilibs = TC.getMultilibs();
|
||||
// FIXME: We need tool chain support for this.
|
||||
llvm::outs() << ".;\n";
|
||||
|
||||
for (MultilibSet::const_iterator I = Multilibs.begin(), E = Multilibs.end();
|
||||
I != E; ++I) {
|
||||
llvm::outs() << *I << "\n";
|
||||
switch (C.getDefaultToolChain().getTriple().getArch()) {
|
||||
default:
|
||||
break;
|
||||
|
||||
case llvm::Triple::x86_64:
|
||||
llvm::outs() << "x86_64;@m64" << "\n";
|
||||
break;
|
||||
|
||||
case llvm::Triple::ppc64:
|
||||
llvm::outs() << "ppc64;@m64" << "\n";
|
||||
break;
|
||||
|
||||
case llvm::Triple::ppc64le:
|
||||
llvm::outs() << "ppc64le;@m64" << "\n";
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (C.getArgs().hasArg(options::OPT_print_multi_directory)) {
|
||||
const MultilibSet &Multilibs = TC.getMultilibs();
|
||||
for (MultilibSet::const_iterator I = Multilibs.begin(), E = Multilibs.end();
|
||||
I != E; ++I) {
|
||||
if (I->gccSuffix().empty())
|
||||
llvm::outs() << ".\n";
|
||||
else {
|
||||
StringRef Suffix(I->gccSuffix());
|
||||
assert(Suffix.front() == '/');
|
||||
llvm::outs() << Suffix.substr(1) << "\n";
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// FIXME: What is the difference between print-multi-directory and
|
||||
// print-multi-os-directory?
|
||||
if (C.getArgs().hasArg(options::OPT_print_multi_directory) ||
|
||||
C.getArgs().hasArg(options::OPT_print_multi_os_directory)) {
|
||||
switch (C.getDefaultToolChain().getTriple().getArch()) {
|
||||
default:
|
||||
case llvm::Triple::x86:
|
||||
case llvm::Triple::ppc:
|
||||
llvm::outs() << "." << "\n";
|
||||
break;
|
||||
|
||||
if (C.getArgs().hasArg(options::OPT_print_multi_os_directory)) {
|
||||
// FIXME: This should print out "lib/../lib", "lib/../lib64", or
|
||||
// "lib/../lib32" as appropriate for the toolchain. For now, print
|
||||
// nothing because it's not supported yet.
|
||||
case llvm::Triple::x86_64:
|
||||
llvm::outs() << "x86_64" << "\n";
|
||||
break;
|
||||
|
||||
case llvm::Triple::ppc64:
|
||||
llvm::outs() << "ppc64" << "\n";
|
||||
break;
|
||||
|
||||
case llvm::Triple::ppc64le:
|
||||
llvm::outs() << "ppc64le" << "\n";
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,347 +0,0 @@
|
|||
//===--- Multilib.cpp - Multilib Implementation ---------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/Driver/Multilib.h"
|
||||
#include "Tools.h"
|
||||
#include "clang/Driver/Options.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/StringSet.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/Option/Arg.h"
|
||||
#include "llvm/Option/ArgList.h"
|
||||
#include "llvm/Option/OptTable.h"
|
||||
#include "llvm/Option/Option.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Support/Regex.h"
|
||||
#include "llvm/Support/YAMLParser.h"
|
||||
#include "llvm/Support/YAMLTraits.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace clang::driver;
|
||||
using namespace clang;
|
||||
using namespace llvm::opt;
|
||||
|
||||
static void normalizePathSegment(std::string &Segment) {
|
||||
StringRef SRS(Segment);
|
||||
if (SRS.empty() || SRS == "/." || SRS == "/" || SRS == ".") {
|
||||
SRS = "";
|
||||
} else {
|
||||
if (SRS.back() == '/')
|
||||
SRS = SRS.drop_back();
|
||||
if (SRS.front() != '/')
|
||||
SRS = ("/" + SRS).str();
|
||||
}
|
||||
Segment = SRS;
|
||||
}
|
||||
|
||||
Multilib::Multilib(StringRef GCCSuffix, StringRef OSSuffix,
|
||||
StringRef IncludeSuffix)
|
||||
: GCCSuffix(GCCSuffix), OSSuffix(OSSuffix), IncludeSuffix(IncludeSuffix) {
|
||||
normalizePathSegment(this->GCCSuffix);
|
||||
normalizePathSegment(this->OSSuffix);
|
||||
normalizePathSegment(this->IncludeSuffix);
|
||||
}
|
||||
|
||||
Multilib &Multilib::gccSuffix(StringRef S) {
|
||||
GCCSuffix = S;
|
||||
normalizePathSegment(GCCSuffix);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Multilib &Multilib::osSuffix(StringRef S) {
|
||||
OSSuffix = S;
|
||||
normalizePathSegment(OSSuffix);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Multilib &Multilib::includeSuffix(StringRef S) {
|
||||
IncludeSuffix = S;
|
||||
normalizePathSegment(IncludeSuffix);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Multilib::print(raw_ostream &OS) const {
|
||||
assert(GCCSuffix.empty() || (StringRef(GCCSuffix).front() == '/'));
|
||||
if (GCCSuffix.empty())
|
||||
OS << ".";
|
||||
else {
|
||||
OS << StringRef(GCCSuffix).drop_front();
|
||||
}
|
||||
OS << ";";
|
||||
for (flags_list::const_iterator I = Flags.begin(), E = Flags.end(); I != E;
|
||||
++I) {
|
||||
if (StringRef(*I).front() == '+')
|
||||
OS << "@" << I->substr(1);
|
||||
}
|
||||
}
|
||||
|
||||
bool Multilib::isValid() const {
|
||||
llvm::StringMap<int> FlagSet;
|
||||
for (unsigned I = 0, N = Flags.size(); I != N; ++I) {
|
||||
StringRef Flag(Flags[I]);
|
||||
llvm::StringMap<int>::iterator SI = FlagSet.find(Flag.substr(1));
|
||||
|
||||
assert(StringRef(Flag).front() == '+' || StringRef(Flag).front() == '-');
|
||||
|
||||
if (SI == FlagSet.end())
|
||||
FlagSet[Flag.substr(1)] = I;
|
||||
else if (Flags[I] != Flags[SI->getValue()])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Multilib::operator==(const Multilib &Other) const {
|
||||
// Check whether the flags sets match
|
||||
// allowing for the match to be order invariant
|
||||
llvm::StringSet<> MyFlags;
|
||||
for (flags_list::const_iterator I = Flags.begin(), E = Flags.end(); I != E;
|
||||
++I) {
|
||||
MyFlags.insert(*I);
|
||||
}
|
||||
for (flags_list::const_iterator I = Other.Flags.begin(),
|
||||
E = Other.Flags.end();
|
||||
I != E; ++I) {
|
||||
if (MyFlags.find(*I) == MyFlags.end())
|
||||
return false;
|
||||
}
|
||||
|
||||
if (osSuffix() != Other.osSuffix())
|
||||
return false;
|
||||
|
||||
if (gccSuffix() != Other.gccSuffix())
|
||||
return false;
|
||||
|
||||
if (includeSuffix() != Other.includeSuffix())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
raw_ostream &clang::driver::operator<<(raw_ostream &OS, const Multilib &M) {
|
||||
M.print(OS);
|
||||
return OS;
|
||||
}
|
||||
|
||||
MultilibSet &MultilibSet::Maybe(const Multilib &M) {
|
||||
Multilib Opposite;
|
||||
// Negate any '+' flags
|
||||
for (Multilib::flags_list::const_iterator I = M.flags().begin(),
|
||||
E = M.flags().end();
|
||||
I != E; ++I) {
|
||||
StringRef Flag(*I);
|
||||
if (Flag.front() == '+')
|
||||
Opposite.flags().push_back(("-" + Flag.substr(1)).str());
|
||||
}
|
||||
return Either(M, Opposite);
|
||||
}
|
||||
|
||||
MultilibSet &MultilibSet::Either(const Multilib &M1, const Multilib &M2) {
|
||||
std::vector<Multilib> Ms;
|
||||
Ms.push_back(M1);
|
||||
Ms.push_back(M2);
|
||||
return Either(Ms);
|
||||
}
|
||||
|
||||
MultilibSet &MultilibSet::Either(const Multilib &M1, const Multilib &M2,
|
||||
const Multilib &M3) {
|
||||
std::vector<Multilib> Ms;
|
||||
Ms.push_back(M1);
|
||||
Ms.push_back(M2);
|
||||
Ms.push_back(M3);
|
||||
return Either(Ms);
|
||||
}
|
||||
|
||||
MultilibSet &MultilibSet::Either(const Multilib &M1, const Multilib &M2,
|
||||
const Multilib &M3, const Multilib &M4) {
|
||||
std::vector<Multilib> Ms;
|
||||
Ms.push_back(M1);
|
||||
Ms.push_back(M2);
|
||||
Ms.push_back(M3);
|
||||
Ms.push_back(M4);
|
||||
return Either(Ms);
|
||||
}
|
||||
|
||||
MultilibSet &MultilibSet::Either(const Multilib &M1, const Multilib &M2,
|
||||
const Multilib &M3, const Multilib &M4,
|
||||
const Multilib &M5) {
|
||||
std::vector<Multilib> Ms;
|
||||
Ms.push_back(M1);
|
||||
Ms.push_back(M2);
|
||||
Ms.push_back(M3);
|
||||
Ms.push_back(M4);
|
||||
Ms.push_back(M5);
|
||||
return Either(Ms);
|
||||
}
|
||||
|
||||
static Multilib compose(const Multilib &Base, const Multilib &New) {
|
||||
SmallString<128> GCCSuffix;
|
||||
llvm::sys::path::append(GCCSuffix, "/", Base.gccSuffix(), New.gccSuffix());
|
||||
SmallString<128> OSSuffix;
|
||||
llvm::sys::path::append(OSSuffix, "/", Base.osSuffix(), New.osSuffix());
|
||||
SmallString<128> IncludeSuffix;
|
||||
llvm::sys::path::append(IncludeSuffix, "/", Base.includeSuffix(),
|
||||
New.includeSuffix());
|
||||
|
||||
Multilib Composed(GCCSuffix.str(), OSSuffix.str(), IncludeSuffix.str());
|
||||
|
||||
Multilib::flags_list &Flags = Composed.flags();
|
||||
|
||||
Flags.insert(Flags.end(), Base.flags().begin(), Base.flags().end());
|
||||
Flags.insert(Flags.end(), New.flags().begin(), New.flags().end());
|
||||
|
||||
return Composed;
|
||||
}
|
||||
|
||||
MultilibSet &
|
||||
MultilibSet::Either(const std::vector<Multilib> &MultilibSegments) {
|
||||
multilib_list Composed;
|
||||
|
||||
if (Multilibs.empty())
|
||||
Multilibs.insert(Multilibs.end(), MultilibSegments.begin(),
|
||||
MultilibSegments.end());
|
||||
else {
|
||||
for (std::vector<Multilib>::const_iterator NewI = MultilibSegments.begin(),
|
||||
NewE = MultilibSegments.end();
|
||||
NewI != NewE; ++NewI) {
|
||||
for (const_iterator BaseI = begin(), BaseE = end(); BaseI != BaseE;
|
||||
++BaseI) {
|
||||
Multilib MO = compose(*BaseI, *NewI);
|
||||
if (MO.isValid())
|
||||
Composed.push_back(MO);
|
||||
}
|
||||
}
|
||||
|
||||
Multilibs = Composed;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
MultilibSet &MultilibSet::FilterOut(const MultilibSet::FilterCallback &F) {
|
||||
filterInPlace(F, Multilibs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
MultilibSet &MultilibSet::FilterOut(std::string Regex) {
|
||||
class REFilter : public MultilibSet::FilterCallback {
|
||||
mutable llvm::Regex R;
|
||||
|
||||
public:
|
||||
REFilter(std::string Regex) : R(Regex) {}
|
||||
bool operator()(const Multilib &M) const LLVM_OVERRIDE {
|
||||
std::string Error;
|
||||
if (!R.isValid(Error)) {
|
||||
llvm::errs() << Error;
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
return R.match(M.gccSuffix());
|
||||
}
|
||||
};
|
||||
|
||||
REFilter REF(Regex);
|
||||
filterInPlace(REF, Multilibs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void MultilibSet::push_back(const Multilib &M) { Multilibs.push_back(M); }
|
||||
|
||||
void MultilibSet::combineWith(const MultilibSet &Other) {
|
||||
Multilibs.insert(Multilibs.end(), Other.begin(), Other.end());
|
||||
}
|
||||
|
||||
bool MultilibSet::select(const Multilib::flags_list &Flags, Multilib &M) const {
|
||||
class FilterFlagsMismatch : public MultilibSet::FilterCallback {
|
||||
llvm::StringMap<bool> FlagSet;
|
||||
|
||||
public:
|
||||
FilterFlagsMismatch(const std::vector<std::string> &Flags) {
|
||||
// Stuff all of the flags into the FlagSet such that a true mappend
|
||||
// indicates the flag was enabled, and a false mappend indicates the
|
||||
// flag was disabled
|
||||
for (Multilib::flags_list::const_iterator I = Flags.begin(),
|
||||
E = Flags.end();
|
||||
I != E; ++I) {
|
||||
FlagSet[StringRef(*I).substr(1)] = isFlagEnabled(*I);
|
||||
}
|
||||
}
|
||||
bool operator()(const Multilib &M) const LLVM_OVERRIDE {
|
||||
for (Multilib::flags_list::const_iterator I = M.flags().begin(),
|
||||
E = M.flags().end();
|
||||
I != E; ++I) {
|
||||
StringRef Flag(*I);
|
||||
llvm::StringMap<bool>::const_iterator SI = FlagSet.find(Flag.substr(1));
|
||||
if (SI != FlagSet.end())
|
||||
if ((*SI).getValue() != isFlagEnabled(Flag))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
private:
|
||||
bool isFlagEnabled(StringRef Flag) const {
|
||||
char Indicator = Flag.front();
|
||||
assert(Indicator == '+' || Indicator == '-');
|
||||
return Indicator == '+';
|
||||
}
|
||||
};
|
||||
|
||||
FilterFlagsMismatch FlagsMismatch(Flags);
|
||||
|
||||
multilib_list Filtered = filterCopy(FlagsMismatch, Multilibs);
|
||||
|
||||
if (Filtered.size() == 0) {
|
||||
return false;
|
||||
} else if (Filtered.size() == 1) {
|
||||
M = Filtered[0];
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: pick the "best" multlib when more than one is suitable
|
||||
assert(false);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void MultilibSet::print(raw_ostream &OS) const {
|
||||
for (const_iterator I = begin(), E = end(); I != E; ++I)
|
||||
OS << *I << "\n";
|
||||
}
|
||||
|
||||
MultilibSet::multilib_list
|
||||
MultilibSet::filterCopy(const MultilibSet::FilterCallback &F,
|
||||
const multilib_list &Ms) {
|
||||
multilib_list Copy(Ms);
|
||||
filterInPlace(F, Copy);
|
||||
return Copy;
|
||||
}
|
||||
|
||||
namespace {
|
||||
// Wrapper for FilterCallback to make operator() nonvirtual so it
|
||||
// can be passed by value to std::remove_if
|
||||
class FilterWrapper {
|
||||
const MultilibSet::FilterCallback &F;
|
||||
public:
|
||||
FilterWrapper(const MultilibSet::FilterCallback &F) : F(F) {}
|
||||
bool operator()(const Multilib &M) const { return F(M); }
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
void MultilibSet::filterInPlace(const MultilibSet::FilterCallback &F,
|
||||
multilib_list &Ms) {
|
||||
Ms.erase(std::remove_if(Ms.begin(), Ms.end(), FilterWrapper(F)), Ms.end());
|
||||
}
|
||||
|
||||
raw_ostream &clang::driver::operator<<(raw_ostream &OS, const MultilibSet &MS) {
|
||||
MS.print(OS);
|
||||
return OS;
|
||||
}
|
|
@ -139,11 +139,11 @@ static const char *GetArmArchForMCpu(StringRef Value) {
|
|||
}
|
||||
|
||||
static bool isSoftFloatABI(const ArgList &Args) {
|
||||
Arg *A = Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
|
||||
Arg *A = Args.getLastArg(options::OPT_msoft_float,
|
||||
options::OPT_mhard_float,
|
||||
options::OPT_mfloat_abi_EQ);
|
||||
if (!A)
|
||||
return false;
|
||||
|
||||
if (!A) return false;
|
||||
|
||||
return A->getOption().matches(options::OPT_msoft_float) ||
|
||||
(A->getOption().matches(options::OPT_mfloat_abi_EQ) &&
|
||||
A->getValue() == StringRef("soft"));
|
||||
|
@ -1175,7 +1175,7 @@ bool Generic_GCC::GCCVersion::isOlderThan(int RHSMajor, int RHSMinor,
|
|||
return false;
|
||||
}
|
||||
|
||||
static llvm::StringRef getGCCToolchainDir(const ArgList &Args) {
|
||||
static StringRef getGCCToolchainDir(const ArgList &Args) {
|
||||
const Arg *A = Args.getLastArg(options::OPT_gcc_toolchain);
|
||||
if (A)
|
||||
return A->getValue();
|
||||
|
@ -1197,6 +1197,7 @@ Generic_GCC::GCCInstallationDetector::init(
|
|||
llvm::Triple BiarchVariantTriple =
|
||||
TargetTriple.isArch32Bit() ? TargetTriple.get64BitArchVariant()
|
||||
: TargetTriple.get32BitArchVariant();
|
||||
llvm::Triple::ArchType TargetArch = TargetTriple.getArch();
|
||||
// The library directories which may contain GCC installations.
|
||||
SmallVector<StringRef, 4> CandidateLibDirs, CandidateBiarchLibDirs;
|
||||
// The compatible GCC triples for this particular architecture.
|
||||
|
@ -1242,7 +1243,7 @@ Generic_GCC::GCCInstallationDetector::init(
|
|||
if (!llvm::sys::fs::exists(LibDir))
|
||||
continue;
|
||||
for (unsigned k = 0, ke = CandidateTripleAliases.size(); k < ke; ++k)
|
||||
ScanLibDirForGCCTriple(TargetTriple, Args, LibDir,
|
||||
ScanLibDirForGCCTriple(TargetArch, Args, LibDir,
|
||||
CandidateTripleAliases[k]);
|
||||
}
|
||||
for (unsigned j = 0, je = CandidateBiarchLibDirs.size(); j < je; ++j) {
|
||||
|
@ -1251,7 +1252,7 @@ Generic_GCC::GCCInstallationDetector::init(
|
|||
continue;
|
||||
for (unsigned k = 0, ke = CandidateBiarchTripleAliases.size(); k < ke;
|
||||
++k)
|
||||
ScanLibDirForGCCTriple(TargetTriple, Args, LibDir,
|
||||
ScanLibDirForGCCTriple(TargetArch, Args, LibDir,
|
||||
CandidateBiarchTripleAliases[k],
|
||||
/*NeedsBiarchSuffix=*/ true);
|
||||
}
|
||||
|
@ -1266,19 +1267,6 @@ void Generic_GCC::GCCInstallationDetector::print(raw_ostream &OS) const {
|
|||
OS << "Found candidate GCC installation: " << *I << "\n";
|
||||
|
||||
OS << "Selected GCC installation: " << GCCInstallPath << "\n";
|
||||
for (MultilibSet::const_iterator I = Multilibs.begin(), E = Multilibs.end();
|
||||
I != E; ++I) {
|
||||
OS << "Candidate multiilb: " << *I << "\n";
|
||||
}
|
||||
OS << "Selected multilib: " << SelectedMultilib << "\n";
|
||||
}
|
||||
|
||||
bool Generic_GCC::GCCInstallationDetector::getBiarchSibling(Multilib &M) const {
|
||||
if (BiarchSibling.hasValue()) {
|
||||
M = BiarchSibling.getValue();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*static*/ void Generic_GCC::GCCInstallationDetector::CollectLibDirsAndTriples(
|
||||
|
@ -1514,45 +1502,11 @@ bool Generic_GCC::GCCInstallationDetector::getBiarchSibling(Multilib &M) const {
|
|||
BiarchTripleAliases.push_back(BiarchTriple.str());
|
||||
}
|
||||
|
||||
namespace {
|
||||
// Filter to remove Multilibs that don't exist as a suffix to Path
|
||||
class FilterNonExistant : public MultilibSet::FilterCallback {
|
||||
std::string Base;
|
||||
public:
|
||||
FilterNonExistant(std::string Base) : Base(Base) {}
|
||||
bool operator()(const Multilib &M) const LLVM_OVERRIDE {
|
||||
return !llvm::sys::fs::exists(Base + M.gccSuffix() + "/crtbegin.o");
|
||||
}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
static void addMultilibFlag(bool Enabled, const char *const Flag,
|
||||
std::vector<std::string> &Flags) {
|
||||
if (Enabled)
|
||||
Flags.push_back(std::string("+") + Flag);
|
||||
else
|
||||
Flags.push_back(std::string("-") + Flag);
|
||||
}
|
||||
|
||||
static bool isMipsArch(llvm::Triple::ArchType Arch) {
|
||||
return Arch == llvm::Triple::mips || Arch == llvm::Triple::mipsel ||
|
||||
Arch == llvm::Triple::mips64 || Arch == llvm::Triple::mips64el;
|
||||
}
|
||||
|
||||
static bool isMips32(llvm::Triple::ArchType Arch) {
|
||||
return Arch == llvm::Triple::mips || Arch == llvm::Triple::mipsel;
|
||||
}
|
||||
|
||||
static bool isMips64(llvm::Triple::ArchType Arch) {
|
||||
return Arch == llvm::Triple::mips64 || Arch == llvm::Triple::mips64el;
|
||||
}
|
||||
|
||||
static bool isMipsEL(llvm::Triple::ArchType Arch) {
|
||||
return Arch == llvm::Triple::mipsel || Arch == llvm::Triple::mips64el;
|
||||
}
|
||||
|
||||
static bool isMipsEB(llvm::Triple::ArchType Arch) {
|
||||
return Arch == llvm::Triple::mips || Arch == llvm::Triple::mips64;
|
||||
return Arch == llvm::Triple::mips ||
|
||||
Arch == llvm::Triple::mipsel ||
|
||||
Arch == llvm::Triple::mips64 ||
|
||||
Arch == llvm::Triple::mips64el;
|
||||
}
|
||||
|
||||
static bool isMips16(const ArgList &Args) {
|
||||
|
@ -1591,8 +1545,39 @@ static bool isMipsNan2008(const ArgList &Args) {
|
|||
return A && A->getValue() == StringRef("2008");
|
||||
}
|
||||
|
||||
bool Generic_GCC::GCCInstallationDetector::findMIPSMultilibs(
|
||||
const llvm::Triple &TargetTriple, StringRef Path,
|
||||
// FIXME: There is the same routine in the Tools.cpp.
|
||||
static bool hasMipsABIArg(const ArgList &Args, const char *Value) {
|
||||
Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
|
||||
return A && (A->getValue() == StringRef(Value));
|
||||
}
|
||||
|
||||
static bool hasCrtBeginObj(Twine Path) {
|
||||
return llvm::sys::fs::exists(Path + "/crtbegin.o");
|
||||
}
|
||||
|
||||
static bool findTargetBiarchSuffix(std::string &Suffix, StringRef Path,
|
||||
llvm::Triple::ArchType TargetArch,
|
||||
const ArgList &Args) {
|
||||
// FIXME: This routine was only intended to model bi-arch toolchains which
|
||||
// use -m32 and -m64 to swap between variants of a target. It shouldn't be
|
||||
// doing ABI-based builtin location for MIPS.
|
||||
if (hasMipsABIArg(Args, "n32"))
|
||||
Suffix = "/n32";
|
||||
else if (TargetArch == llvm::Triple::x86_64 ||
|
||||
TargetArch == llvm::Triple::ppc64 ||
|
||||
TargetArch == llvm::Triple::sparcv9 ||
|
||||
TargetArch == llvm::Triple::systemz ||
|
||||
TargetArch == llvm::Triple::mips64 ||
|
||||
TargetArch == llvm::Triple::mips64el)
|
||||
Suffix = "/64";
|
||||
else
|
||||
Suffix = "/32";
|
||||
|
||||
return hasCrtBeginObj(Path + Suffix);
|
||||
}
|
||||
|
||||
void Generic_GCC::GCCInstallationDetector::findMIPSABIDirSuffix(
|
||||
std::string &Suffix, llvm::Triple::ArchType TargetArch, StringRef Path,
|
||||
const llvm::opt::ArgList &Args) {
|
||||
// Some MIPS toolchains put libraries and object files compiled
|
||||
// using different options in to the sub-directoris which names
|
||||
|
@ -1619,286 +1604,69 @@ bool Generic_GCC::GCCInstallationDetector::findMIPSMultilibs(
|
|||
// /usr
|
||||
// /lib <= crt*.o files compiled with '-mips32'
|
||||
|
||||
FilterNonExistant NonExistant(Path);
|
||||
|
||||
// Check for FSF toolchain multilibs
|
||||
MultilibSet FSFMipsMultilibs;
|
||||
{
|
||||
Multilib MArchMips32 = Multilib()
|
||||
.gccSuffix("/mips32")
|
||||
.osSuffix("/mips32")
|
||||
.includeSuffix("/mips32")
|
||||
.flag("+m32").flag("-m64").flag("-mmicromips").flag("-march=mips32r2");
|
||||
|
||||
Multilib MArchMicroMips = Multilib()
|
||||
.gccSuffix("/micromips")
|
||||
.osSuffix("/micromips")
|
||||
.includeSuffix("/micromips")
|
||||
.flag("+m32").flag("-m64").flag("+mmicromips");
|
||||
|
||||
Multilib MArchMips64r2 = Multilib()
|
||||
.gccSuffix("/mips64r2")
|
||||
.osSuffix("/mips64r2")
|
||||
.includeSuffix("/mips64r2")
|
||||
.flag("-m32").flag("+m64").flag("+march=mips64r2");
|
||||
|
||||
Multilib MArchMips64 = Multilib()
|
||||
.gccSuffix("/mips64")
|
||||
.osSuffix("/mips64")
|
||||
.includeSuffix("/mips64")
|
||||
.flag("-m32").flag("+m64").flag("-march=mips64r2");
|
||||
|
||||
Multilib MArchDefault = Multilib()
|
||||
.flag("+m32").flag("-m64").flag("+march=mips32r2");
|
||||
|
||||
Multilib Mips16 = Multilib()
|
||||
.gccSuffix("/mips16")
|
||||
.osSuffix("/mips16")
|
||||
.includeSuffix("/mips16")
|
||||
.flag("+mips16");
|
||||
|
||||
Multilib MAbi64 = Multilib()
|
||||
.gccSuffix("/64")
|
||||
.osSuffix("/64")
|
||||
.includeSuffix("/64")
|
||||
.flag("+mabi=64").flag("-mabi=n32").flag("-m32");
|
||||
|
||||
Multilib LittleEndian = Multilib()
|
||||
.gccSuffix("/el")
|
||||
.osSuffix("/el")
|
||||
.includeSuffix("/el")
|
||||
.flag("+EL").flag("-EB");
|
||||
|
||||
Multilib SoftFloat = Multilib()
|
||||
.gccSuffix("/sof")
|
||||
.osSuffix("/sof")
|
||||
.includeSuffix("/sof")
|
||||
.flag("+msoft-float");
|
||||
|
||||
Multilib FP64 = Multilib()
|
||||
.gccSuffix("/fp64")
|
||||
.osSuffix("/fp64")
|
||||
.includeSuffix("/fp64")
|
||||
.flag("+mfp64");
|
||||
|
||||
Multilib Nan2008 = Multilib()
|
||||
.gccSuffix("/nan2008")
|
||||
.osSuffix("/nan2008")
|
||||
.includeSuffix("/nan2008")
|
||||
.flag("+mnan=2008");
|
||||
|
||||
FSFMipsMultilibs = MultilibSet()
|
||||
.Either(MArchMips32, MArchMicroMips,
|
||||
MArchMips64r2, MArchMips64, MArchDefault)
|
||||
.Maybe(Mips16)
|
||||
.FilterOut("/mips64/mips16")
|
||||
.FilterOut("/mips64r2/mips16")
|
||||
.FilterOut("/micromips/mips16")
|
||||
.Maybe(MAbi64)
|
||||
.FilterOut("/micromips/64")
|
||||
.FilterOut("/mips32/64")
|
||||
.FilterOut("^/64")
|
||||
.FilterOut("/mips16/64")
|
||||
.Maybe(LittleEndian)
|
||||
.Maybe(SoftFloat)
|
||||
.Maybe(FP64)
|
||||
.Maybe(Nan2008)
|
||||
.FilterOut(".*sof/nan2008")
|
||||
.FilterOut(".*sof/fp64")
|
||||
.FilterOut(NonExistant);
|
||||
}
|
||||
|
||||
// Check for Code Sourcery toolchain multilibs
|
||||
MultilibSet CSMipsMultilibs;
|
||||
{
|
||||
Multilib MArchMips16 = Multilib()
|
||||
.gccSuffix("/mips16")
|
||||
.osSuffix("/mips16")
|
||||
.includeSuffix("/mips16")
|
||||
.flag("+m32").flag("+mips16");
|
||||
|
||||
Multilib MArchMicroMips = Multilib()
|
||||
.gccSuffix("/micromips")
|
||||
.osSuffix("/micromips")
|
||||
.includeSuffix("/micromips")
|
||||
.flag("+m32").flag("+mmicromips");
|
||||
|
||||
Multilib MArchDefault = Multilib()
|
||||
.flag("-mips16").flag("-mmicromips");
|
||||
|
||||
Multilib SoftFloat = Multilib()
|
||||
.gccSuffix("/soft-float")
|
||||
.osSuffix("/soft-float")
|
||||
.includeSuffix("/soft-float")
|
||||
.flag("+msoft-float");
|
||||
|
||||
Multilib Nan2008 = Multilib()
|
||||
.gccSuffix("/nan2008")
|
||||
.osSuffix("/nan2008")
|
||||
.includeSuffix("/nan2008")
|
||||
.flag("+mnan=2008");
|
||||
|
||||
Multilib DefaultFloat = Multilib()
|
||||
.flag("-msoft-float").flag("-mnan=2008");
|
||||
|
||||
Multilib LittleEndian = Multilib()
|
||||
.gccSuffix("/el")
|
||||
.osSuffix("/el")
|
||||
.includeSuffix("/el")
|
||||
.flag("+EL").flag("-EB");
|
||||
|
||||
// Note that this one's osSuffix is ""
|
||||
Multilib MAbi64 = Multilib()
|
||||
.gccSuffix("/64")
|
||||
.includeSuffix("/64")
|
||||
.flag("+mabi=64").flag("-mabi=n32").flag("-m32");
|
||||
|
||||
CSMipsMultilibs = MultilibSet()
|
||||
.Either(MArchMips16, MArchMicroMips, MArchDefault)
|
||||
.Either(SoftFloat, Nan2008, DefaultFloat)
|
||||
.FilterOut("/micromips/nan2008")
|
||||
.FilterOut("/mips16/nan2008")
|
||||
.Maybe(LittleEndian)
|
||||
.Maybe(MAbi64)
|
||||
.FilterOut("/mips16.*/64")
|
||||
.FilterOut("/micromips.*/64")
|
||||
.FilterOut(NonExistant);
|
||||
}
|
||||
|
||||
MultilibSet AndroidMipsMultilibs = MultilibSet()
|
||||
.Maybe(Multilib("/mips-r2").flag("+march=mips32r2"))
|
||||
.FilterOut(NonExistant);
|
||||
|
||||
MultilibSet DebianMipsMultilibs;
|
||||
{
|
||||
Multilib MAbiN32 = Multilib()
|
||||
.gccSuffix("/n32")
|
||||
.includeSuffix("/n32")
|
||||
.flag("+mabi=n32");
|
||||
|
||||
Multilib M64 = Multilib()
|
||||
.gccSuffix("/64")
|
||||
.includeSuffix("/64")
|
||||
.flag("+m64").flag("-m32").flag("-mabi=n32");
|
||||
|
||||
Multilib M32 = Multilib()
|
||||
.flag("-m64").flag("+m32").flag("-mabi=n32");
|
||||
|
||||
DebianMipsMultilibs = MultilibSet()
|
||||
.Either(M32, M64, MAbiN32)
|
||||
.FilterOut(NonExistant);
|
||||
}
|
||||
|
||||
Multilibs.clear();
|
||||
|
||||
// Decide which MultilibSet matches best for the given path
|
||||
// (we do this rather than combining them all because there is a
|
||||
// a bit of overlap in the directories that each specifies)
|
||||
if (TargetTriple.getEnvironment() == llvm::Triple::Android)
|
||||
Multilibs.combineWith(AndroidMipsMultilibs);
|
||||
else if (DebianMipsMultilibs.size() == 3) {
|
||||
Multilibs.combineWith(DebianMipsMultilibs);
|
||||
BiarchSibling = Multilib();
|
||||
} else if (FSFMipsMultilibs.size() > CSMipsMultilibs.size())
|
||||
Multilibs.combineWith(FSFMipsMultilibs);
|
||||
else
|
||||
Multilibs.combineWith(CSMipsMultilibs);
|
||||
|
||||
llvm::Triple::ArchType TargetArch = TargetTriple.getArch();
|
||||
|
||||
Multilib::flags_list Flags;
|
||||
addMultilibFlag(isMips32(TargetArch), "m32", Flags);
|
||||
addMultilibFlag(isMips64(TargetArch), "m64", Flags);
|
||||
addMultilibFlag(isMips16(Args), "mips16", Flags);
|
||||
addMultilibFlag(isMips32r2(Args), "march=mips32r2", Flags);
|
||||
addMultilibFlag(isMips64r2(Args), "march=mips64r2", Flags);
|
||||
addMultilibFlag(isMicroMips(Args), "mmicromips", Flags);
|
||||
addMultilibFlag(isMipsFP64(Args), "mfp64", Flags);
|
||||
addMultilibFlag(!isMipsFP64(Args), "mfp32", Flags);
|
||||
addMultilibFlag(isMipsNan2008(Args), "mnan=2008", Flags);
|
||||
addMultilibFlag(tools::mips::hasMipsAbiArg(Args, "n32"), "mabi=n32", Flags);
|
||||
// Default is to assume mabi=64
|
||||
bool IsMABI64 =
|
||||
tools::mips::hasMipsAbiArg(Args, "64") ||
|
||||
(!tools::mips::hasMipsAbiArg(Args, "n32") && isMips64(TargetArch));
|
||||
addMultilibFlag(IsMABI64, "mabi=64", Flags);
|
||||
addMultilibFlag(isSoftFloatABI(Args), "msoft-float", Flags);
|
||||
addMultilibFlag(isSoftFloatABI(Args), "mfloat-abi=soft", Flags);
|
||||
addMultilibFlag(!isSoftFloatABI(Args), "mhard-float", Flags);
|
||||
addMultilibFlag(!isSoftFloatABI(Args), "mfloat-abi=hard", Flags);
|
||||
addMultilibFlag(isMipsEL(TargetArch), "EL", Flags);
|
||||
addMultilibFlag(isMipsEB(TargetArch), "EB", Flags);
|
||||
|
||||
return Multilibs.select(Flags, SelectedMultilib);
|
||||
}
|
||||
|
||||
bool Generic_GCC::GCCInstallationDetector::findBiarchMultilibs(
|
||||
const llvm::Triple &TargetTriple, StringRef Path, const ArgList &Args,
|
||||
bool NeedsBiarchSuffix) {
|
||||
|
||||
// Some versions of SUSE and Fedora on ppc64 put 32-bit libs
|
||||
// in what would normally be GCCInstallPath and put the 64-bit
|
||||
// libs in a subdirectory named 64. The simple logic we follow is that
|
||||
// *if* there is a subdirectory of the right name with crtbegin.o in it,
|
||||
// we use that. If not, and if not a biarch triple alias, we look for
|
||||
// crtbegin.o without the subdirectory.
|
||||
|
||||
Multilib Default;
|
||||
Multilib Alt64 = Multilib()
|
||||
.gccSuffix("/64")
|
||||
.includeSuffix("/64")
|
||||
.flag("-m32").flag("+m64");
|
||||
Multilib Alt32 = Multilib()
|
||||
.gccSuffix("/32")
|
||||
.includeSuffix("/32")
|
||||
.flag("+m32").flag("-m64");
|
||||
|
||||
FilterNonExistant NonExistant(Path);
|
||||
|
||||
// Decide whether the default multilib is 32bit, correcting for
|
||||
// when the default multilib and the alternate appear backwards
|
||||
bool DefaultIs32Bit;
|
||||
if (TargetTriple.isArch32Bit() && !NonExistant(Alt32))
|
||||
DefaultIs32Bit = false;
|
||||
else if (TargetTriple.isArch64Bit() && !NonExistant(Alt64))
|
||||
DefaultIs32Bit = true;
|
||||
else {
|
||||
if (NeedsBiarchSuffix)
|
||||
DefaultIs32Bit = TargetTriple.isArch64Bit();
|
||||
// Check FSF Toolchain path
|
||||
Suffix.clear();
|
||||
if (TargetArch == llvm::Triple::mips ||
|
||||
TargetArch == llvm::Triple::mipsel) {
|
||||
if (isMicroMips(Args))
|
||||
Suffix += "/micromips";
|
||||
else if (isMips32r2(Args))
|
||||
Suffix += "";
|
||||
else
|
||||
DefaultIs32Bit = TargetTriple.isArch32Bit();
|
||||
Suffix += "/mips32";
|
||||
|
||||
if (isMips16(Args))
|
||||
Suffix += "/mips16";
|
||||
} else {
|
||||
if (isMips64r2(Args))
|
||||
Suffix += hasMipsABIArg(Args, "n32") ? "/mips64r2" : "/mips64r2/64";
|
||||
else
|
||||
Suffix += hasMipsABIArg(Args, "n32") ? "/mips64" : "/mips64/64";
|
||||
}
|
||||
|
||||
if (DefaultIs32Bit)
|
||||
Default.flag("+m32").flag("-m64");
|
||||
else
|
||||
Default.flag("-m32").flag("+m64");
|
||||
if (TargetArch == llvm::Triple::mipsel ||
|
||||
TargetArch == llvm::Triple::mips64el)
|
||||
Suffix += "/el";
|
||||
|
||||
Multilibs.push_back(Default);
|
||||
Multilibs.push_back(Alt64);
|
||||
Multilibs.push_back(Alt32);
|
||||
if (isSoftFloatABI(Args))
|
||||
Suffix += "/sof";
|
||||
else {
|
||||
if (isMipsFP64(Args))
|
||||
Suffix += "/fp64";
|
||||
|
||||
Multilibs.FilterOut(NonExistant);
|
||||
|
||||
Multilib::flags_list Flags;
|
||||
addMultilibFlag(TargetTriple.isArch64Bit(), "m64", Flags);
|
||||
addMultilibFlag(TargetTriple.isArch32Bit(), "m32", Flags);
|
||||
|
||||
if (!Multilibs.select(Flags, SelectedMultilib))
|
||||
return false;
|
||||
|
||||
if (SelectedMultilib == Alt64 || SelectedMultilib == Alt32) {
|
||||
BiarchSibling = Default;
|
||||
if (isMipsNan2008(Args))
|
||||
Suffix += "/nan2008";
|
||||
}
|
||||
|
||||
return true;
|
||||
if (hasCrtBeginObj(Path + Suffix))
|
||||
return;
|
||||
|
||||
// Check Code Sourcery Toolchain path
|
||||
Suffix.clear();
|
||||
if (isMips16(Args))
|
||||
Suffix += "/mips16";
|
||||
else if (isMicroMips(Args))
|
||||
Suffix += "/micromips";
|
||||
|
||||
if (isSoftFloatABI(Args))
|
||||
Suffix += "/soft-float";
|
||||
else if (isMipsNan2008(Args))
|
||||
Suffix += "/nan2008";
|
||||
|
||||
if (TargetArch == llvm::Triple::mipsel ||
|
||||
TargetArch == llvm::Triple::mips64el)
|
||||
Suffix += "/el";
|
||||
|
||||
if (hasCrtBeginObj(Path + Suffix))
|
||||
return;
|
||||
|
||||
Suffix.clear();
|
||||
}
|
||||
|
||||
void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple(
|
||||
const llvm::Triple &TargetTriple, const ArgList &Args,
|
||||
llvm::Triple::ArchType TargetArch, const ArgList &Args,
|
||||
const std::string &LibDir, StringRef CandidateTriple,
|
||||
bool NeedsBiarchSuffix) {
|
||||
llvm::Triple::ArchType TargetArch = TargetTriple.getArch();
|
||||
// There are various different suffixes involving the triple we
|
||||
// check for. We also record what is necessary to walk from each back
|
||||
// up to the lib directory.
|
||||
|
@ -1943,18 +1711,28 @@ void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple(
|
|||
if (CandidateVersion <= Version)
|
||||
continue;
|
||||
|
||||
Multilibs.clear();
|
||||
SelectedMultilib = Multilib();
|
||||
BiarchSibling.reset();
|
||||
std::string MIPSABIDirSuffix;
|
||||
if (isMipsArch(TargetArch))
|
||||
findMIPSABIDirSuffix(MIPSABIDirSuffix, TargetArch, LI->path(), Args);
|
||||
|
||||
// Debian mips multilibs behave more like the rest of the biarch ones,
|
||||
// so handle them there
|
||||
if (isMipsArch(TargetArch)) {
|
||||
if (!findMIPSMultilibs(TargetTriple, LI->path(), Args))
|
||||
continue;
|
||||
} else if (!findBiarchMultilibs(TargetTriple, LI->path(), Args,
|
||||
NeedsBiarchSuffix))
|
||||
// Some versions of SUSE and Fedora on ppc64 put 32-bit libs
|
||||
// in what would normally be GCCInstallPath and put the 64-bit
|
||||
// libs in a subdirectory named 64. The simple logic we follow is that
|
||||
// *if* there is a subdirectory of the right name with crtbegin.o in it,
|
||||
// we use that. If not, and if not a biarch triple alias, we look for
|
||||
// crtbegin.o without the subdirectory.
|
||||
|
||||
std::string BiarchSuffix;
|
||||
if (findTargetBiarchSuffix(BiarchSuffix,
|
||||
LI->path() + MIPSABIDirSuffix,
|
||||
TargetArch, Args)) {
|
||||
GCCBiarchSuffix = BiarchSuffix;
|
||||
} else if (NeedsBiarchSuffix ||
|
||||
!hasCrtBeginObj(LI->path() + MIPSABIDirSuffix)) {
|
||||
continue;
|
||||
} else {
|
||||
GCCBiarchSuffix.clear();
|
||||
}
|
||||
|
||||
Version = CandidateVersion;
|
||||
GCCTriple.setTriple(CandidateTriple);
|
||||
|
@ -1963,6 +1741,7 @@ void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple(
|
|||
// Linux.
|
||||
GCCInstallPath = LibDir + LibSuffixes[i] + "/" + VersionText.str();
|
||||
GCCParentLibPath = GCCInstallPath + InstallSuffixes[i];
|
||||
GCCMIPSABIDirSuffix = MIPSABIDirSuffix;
|
||||
IsValid = true;
|
||||
}
|
||||
}
|
||||
|
@ -2471,9 +2250,9 @@ NetBSD::NetBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
|
|||
break;
|
||||
case llvm::Triple::mips64:
|
||||
case llvm::Triple::mips64el:
|
||||
if (tools::mips::hasMipsAbiArg(Args, "o32"))
|
||||
if (hasMipsABIArg(Args, "o32"))
|
||||
getFilePaths().push_back("=/usr/lib/o32");
|
||||
else if (tools::mips::hasMipsAbiArg(Args, "64"))
|
||||
else if (hasMipsABIArg(Args, "64"))
|
||||
getFilePaths().push_back("=/usr/lib/64");
|
||||
break;
|
||||
default:
|
||||
|
@ -2787,24 +2566,25 @@ static void addPathIfExists(Twine Path, ToolChain::path_list &Paths) {
|
|||
if (llvm::sys::fs::exists(Path)) Paths.push_back(Path.str());
|
||||
}
|
||||
|
||||
static StringRef getOSLibDir(const llvm::Triple &Triple, const ArgList &Args) {
|
||||
static StringRef getMultilibDir(const llvm::Triple &Triple,
|
||||
const ArgList &Args) {
|
||||
if (isMipsArch(Triple.getArch())) {
|
||||
// lib32 directory has a special meaning on MIPS targets.
|
||||
// It contains N32 ABI binaries. Use this folder if produce
|
||||
// code for N32 ABI only.
|
||||
if (tools::mips::hasMipsAbiArg(Args, "n32"))
|
||||
if (hasMipsABIArg(Args, "n32"))
|
||||
return "lib32";
|
||||
return Triple.isArch32Bit() ? "lib" : "lib64";
|
||||
}
|
||||
|
||||
// It happens that only x86 and PPC use the 'lib32' variant of oslibdir, and
|
||||
// It happens that only x86 and PPC use the 'lib32' variant of multilib, and
|
||||
// using that variant while targeting other architectures causes problems
|
||||
// because the libraries are laid out in shared system roots that can't cope
|
||||
// with a 'lib32' library search path being considered. So we only enable
|
||||
// with a 'lib32' multilib search path being considered. So we only enable
|
||||
// them when we know we may need it.
|
||||
//
|
||||
// FIXME: This is a bit of a hack. We should really unify this code for
|
||||
// reasoning about oslibdir spellings with the lib dir spellings in the
|
||||
// reasoning about multilib spellings with the lib dir spellings in the
|
||||
// GCCInstallationDetector, but that is a more significant refactoring.
|
||||
if (Triple.getArch() == llvm::Triple::x86 ||
|
||||
Triple.getArch() == llvm::Triple::ppc)
|
||||
|
@ -2816,7 +2596,6 @@ static StringRef getOSLibDir(const llvm::Triple &Triple, const ArgList &Args) {
|
|||
Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
|
||||
: Generic_ELF(D, Triple, Args) {
|
||||
GCCInstallation.init(D, Triple, Args);
|
||||
Multilibs = GCCInstallation.getMultilibs();
|
||||
llvm::Triple::ArchType Arch = Triple.getArch();
|
||||
std::string SysRoot = computeSysRoot();
|
||||
|
||||
|
@ -2884,20 +2663,29 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
|
|||
// to the link paths.
|
||||
path_list &Paths = getFilePaths();
|
||||
|
||||
const std::string OSLibDir = getOSLibDir(Triple, Args);
|
||||
const std::string Multilib = getMultilibDir(Triple, Args);
|
||||
const std::string MultiarchTriple = getMultiarchTriple(Triple, SysRoot);
|
||||
|
||||
// Add the multilib suffixed paths where they are available.
|
||||
if (GCCInstallation.isValid()) {
|
||||
const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
|
||||
const std::string &LibPath = GCCInstallation.getParentLibPath();
|
||||
const Multilib &Multilib = GCCInstallation.getMultilib();
|
||||
|
||||
// Sourcery CodeBench MIPS toolchain holds some libraries under
|
||||
// a biarch-like suffix of the GCC installation.
|
||||
addPathIfExists((GCCInstallation.getInstallPath() +
|
||||
Multilib.gccSuffix()),
|
||||
Paths);
|
||||
//
|
||||
// FIXME: It would be cleaner to model this as a variant of bi-arch. IE,
|
||||
// instead of a '64' biarch suffix it would be 'el' or something.
|
||||
if (IsAndroid && IsMips && isMips32r2(Args)) {
|
||||
assert(GCCInstallation.getBiarchSuffix().empty() &&
|
||||
"Unexpected bi-arch suffix");
|
||||
addPathIfExists(GCCInstallation.getInstallPath() + "/mips-r2", Paths);
|
||||
} else {
|
||||
addPathIfExists((GCCInstallation.getInstallPath() +
|
||||
GCCInstallation.getMIPSABIDirSuffix() +
|
||||
GCCInstallation.getBiarchSuffix()),
|
||||
Paths);
|
||||
}
|
||||
|
||||
// GCC cross compiling toolchains will install target libraries which ship
|
||||
// as part of the toolchain under <prefix>/<triple>/<libdir> rather than as
|
||||
|
@ -2917,8 +2705,8 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
|
|||
//
|
||||
// Note that this matches the GCC behavior. See the below comment for where
|
||||
// Clang diverges from GCC's behavior.
|
||||
addPathIfExists(LibPath + "/../" + GCCTriple.str() + "/lib/../" + OSLibDir +
|
||||
Multilib.osSuffix(),
|
||||
addPathIfExists(LibPath + "/../" + GCCTriple.str() + "/lib/../" + Multilib +
|
||||
GCCInstallation.getMIPSABIDirSuffix(),
|
||||
Paths);
|
||||
|
||||
// If the GCC installation we found is inside of the sysroot, we want to
|
||||
|
@ -2932,45 +2720,42 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
|
|||
// a bug.
|
||||
if (StringRef(LibPath).startswith(SysRoot)) {
|
||||
addPathIfExists(LibPath + "/" + MultiarchTriple, Paths);
|
||||
addPathIfExists(LibPath + "/../" + OSLibDir, Paths);
|
||||
addPathIfExists(LibPath + "/../" + Multilib, Paths);
|
||||
}
|
||||
}
|
||||
|
||||
// Similar to the logic for GCC above, if we currently running Clang inside
|
||||
// of the requested system root, add its parent library paths to
|
||||
// of the requested system root, add its parent multilib library paths to
|
||||
// those searched.
|
||||
// FIXME: It's not clear whether we should use the driver's installed
|
||||
// directory ('Dir' below) or the ResourceDir.
|
||||
if (StringRef(D.Dir).startswith(SysRoot)) {
|
||||
addPathIfExists(D.Dir + "/../lib/" + MultiarchTriple, Paths);
|
||||
addPathIfExists(D.Dir + "/../" + OSLibDir, Paths);
|
||||
addPathIfExists(D.Dir + "/../" + Multilib, Paths);
|
||||
}
|
||||
|
||||
addPathIfExists(SysRoot + "/lib/" + MultiarchTriple, Paths);
|
||||
addPathIfExists(SysRoot + "/lib/../" + OSLibDir, Paths);
|
||||
addPathIfExists(SysRoot + "/lib/../" + Multilib, Paths);
|
||||
addPathIfExists(SysRoot + "/usr/lib/" + MultiarchTriple, Paths);
|
||||
addPathIfExists(SysRoot + "/usr/lib/../" + OSLibDir, Paths);
|
||||
addPathIfExists(SysRoot + "/usr/lib/../" + Multilib, Paths);
|
||||
|
||||
// Try walking via the GCC triple path in case of biarch or multiarch GCC
|
||||
// installations with strange symlinks.
|
||||
if (GCCInstallation.isValid()) {
|
||||
addPathIfExists(SysRoot + "/usr/lib/" + GCCInstallation.getTriple().str() +
|
||||
"/../../" + OSLibDir, Paths);
|
||||
"/../../" + Multilib, Paths);
|
||||
|
||||
// Add the 'other' biarch variant path
|
||||
Multilib BiarchSibling;
|
||||
if (GCCInstallation.getBiarchSibling(BiarchSibling)) {
|
||||
// Add the non-multilib suffixed paths (if potentially different).
|
||||
const std::string &LibPath = GCCInstallation.getParentLibPath();
|
||||
const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
|
||||
if (!GCCInstallation.getBiarchSuffix().empty())
|
||||
addPathIfExists(GCCInstallation.getInstallPath() +
|
||||
BiarchSibling.gccSuffix(), Paths);
|
||||
}
|
||||
GCCInstallation.getMIPSABIDirSuffix(), Paths);
|
||||
|
||||
// See comments above on the multilib variant for details of why this is
|
||||
// included even from outside the sysroot.
|
||||
const std::string &LibPath = GCCInstallation.getParentLibPath();
|
||||
const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
|
||||
const Multilib &Multilib = GCCInstallation.getMultilib();
|
||||
addPathIfExists(LibPath + "/../" + GCCTriple.str() +
|
||||
"/lib" + Multilib.osSuffix(), Paths);
|
||||
"/lib" + GCCInstallation.getMIPSABIDirSuffix(), Paths);
|
||||
|
||||
// See comments above on the multilib variant for details of why this is
|
||||
// only included from within the sysroot.
|
||||
|
@ -3019,15 +2804,15 @@ std::string Linux::computeSysRoot() const {
|
|||
|
||||
const StringRef InstallDir = GCCInstallation.getInstallPath();
|
||||
const StringRef TripleStr = GCCInstallation.getTriple().str();
|
||||
const Multilib &Multilib = GCCInstallation.getMultilib();
|
||||
const StringRef MIPSABIDirSuffix = GCCInstallation.getMIPSABIDirSuffix();
|
||||
|
||||
std::string Path = (InstallDir + "/../../../../" + TripleStr + "/libc" +
|
||||
Multilib.osSuffix()).str();
|
||||
MIPSABIDirSuffix).str();
|
||||
|
||||
if (llvm::sys::fs::exists(Path))
|
||||
return Path;
|
||||
|
||||
Path = (InstallDir + "/../../../../sysroot" + Multilib.osSuffix()).str();
|
||||
Path = (InstallDir + "/../../../../sysroot" + MIPSABIDirSuffix).str();
|
||||
|
||||
if (llvm::sys::fs::exists(Path))
|
||||
return Path;
|
||||
|
@ -3183,16 +2968,17 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
|
|||
/// libstdc++ installation.
|
||||
/*static*/ bool Linux::addLibStdCXXIncludePaths(Twine Base, Twine Suffix,
|
||||
Twine TargetArchDir,
|
||||
Twine IncludeSuffix,
|
||||
Twine BiarchSuffix,
|
||||
Twine MIPSABIDirSuffix,
|
||||
const ArgList &DriverArgs,
|
||||
ArgStringList &CC1Args) {
|
||||
if (!addLibStdCXXIncludePaths(Base + Suffix,
|
||||
TargetArchDir + IncludeSuffix,
|
||||
TargetArchDir + MIPSABIDirSuffix + BiarchSuffix,
|
||||
DriverArgs, CC1Args))
|
||||
return false;
|
||||
|
||||
addSystemInclude(DriverArgs, CC1Args, Base + "/" + TargetArchDir + Suffix
|
||||
+ IncludeSuffix);
|
||||
+ MIPSABIDirSuffix + BiarchSuffix);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -3236,12 +3022,13 @@ void Linux::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
|
|||
StringRef LibDir = GCCInstallation.getParentLibPath();
|
||||
StringRef InstallDir = GCCInstallation.getInstallPath();
|
||||
StringRef TripleStr = GCCInstallation.getTriple().str();
|
||||
const Multilib &Multilib = GCCInstallation.getMultilib();
|
||||
StringRef MIPSABIDirSuffix = GCCInstallation.getMIPSABIDirSuffix();
|
||||
StringRef BiarchSuffix = GCCInstallation.getBiarchSuffix();
|
||||
const GCCVersion &Version = GCCInstallation.getVersion();
|
||||
|
||||
if (addLibStdCXXIncludePaths(LibDir.str() + "/../include",
|
||||
"/c++/" + Version.Text, TripleStr,
|
||||
Multilib.includeSuffix(), DriverArgs, CC1Args))
|
||||
"/c++/" + Version.Text, TripleStr, BiarchSuffix,
|
||||
MIPSABIDirSuffix, DriverArgs, CC1Args))
|
||||
return;
|
||||
|
||||
const std::string LibStdCXXIncludePathCandidates[] = {
|
||||
|
@ -3260,7 +3047,7 @@ void Linux::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
|
|||
for (unsigned i = 0; i < llvm::array_lengthof(LibStdCXXIncludePathCandidates);
|
||||
++i) {
|
||||
if (addLibStdCXXIncludePaths(LibStdCXXIncludePathCandidates[i],
|
||||
TripleStr + Multilib.includeSuffix(),
|
||||
TripleStr + MIPSABIDirSuffix + BiarchSuffix,
|
||||
DriverArgs, CC1Args))
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -13,10 +13,8 @@
|
|||
#include "Tools.h"
|
||||
#include "clang/Basic/VersionTuple.h"
|
||||
#include "clang/Driver/Action.h"
|
||||
#include "clang/Driver/Multilib.h"
|
||||
#include "clang/Driver/ToolChain.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
@ -69,6 +67,7 @@ protected:
|
|||
bool operator>=(const GCCVersion &RHS) const { return !(*this < RHS); }
|
||||
};
|
||||
|
||||
|
||||
/// \brief This is a class to find a viable GCC installation for Clang to
|
||||
/// use.
|
||||
///
|
||||
|
@ -81,13 +80,9 @@ protected:
|
|||
|
||||
// FIXME: These might be better as path objects.
|
||||
std::string GCCInstallPath;
|
||||
std::string GCCBiarchSuffix;
|
||||
std::string GCCParentLibPath;
|
||||
|
||||
/// The primary multilib appropriate for the given flags.
|
||||
Multilib SelectedMultilib;
|
||||
/// On Biarch systems, this corresponds to the default multilib when
|
||||
/// targeting the non-default multilib. Otherwise, it is empty.
|
||||
llvm::Optional<Multilib> BiarchSibling;
|
||||
std::string GCCMIPSABIDirSuffix;
|
||||
|
||||
GCCVersion Version;
|
||||
|
||||
|
@ -95,9 +90,6 @@ protected:
|
|||
// order to print out detailed information in verbose mode.
|
||||
std::set<std::string> CandidateGCCInstallPaths;
|
||||
|
||||
/// The set of multilibs that the detected installation supports.
|
||||
MultilibSet Multilibs;
|
||||
|
||||
public:
|
||||
GCCInstallationDetector() : IsValid(false) {}
|
||||
void init(const Driver &D, const llvm::Triple &TargetTriple,
|
||||
|
@ -112,18 +104,26 @@ protected:
|
|||
/// \brief Get the detected GCC installation path.
|
||||
StringRef getInstallPath() const { return GCCInstallPath; }
|
||||
|
||||
/// \brief Get the detected GCC installation path suffix for the bi-arch
|
||||
/// target variant.
|
||||
StringRef getBiarchSuffix() const { return GCCBiarchSuffix; }
|
||||
|
||||
/// \brief Get the detected GCC parent lib path.
|
||||
StringRef getParentLibPath() const { return GCCParentLibPath; }
|
||||
|
||||
/// \brief Get the detected Multilib
|
||||
const Multilib &getMultilib() const { return SelectedMultilib; }
|
||||
|
||||
/// \brief Get the whole MultilibSet
|
||||
const MultilibSet &getMultilibs() const { return Multilibs; }
|
||||
|
||||
/// Get the biarch sibling multilib (if it exists).
|
||||
/// \return true iff such a sibling exists
|
||||
bool getBiarchSibling(Multilib &M) const;
|
||||
/// \brief Get the detected GCC MIPS ABI directory suffix.
|
||||
///
|
||||
/// This is used as a suffix both to the install directory of GCC and as
|
||||
/// a suffix to its parent lib path in order to select a MIPS ABI-specific
|
||||
/// subdirectory.
|
||||
///
|
||||
/// This will always be empty for any non-MIPS target.
|
||||
///
|
||||
// FIXME: This probably shouldn't exist at all, and should be factored
|
||||
// into the multiarch and/or biarch support. Please don't add more uses of
|
||||
// this interface, it is meant as a legacy crutch for the MIPS driver
|
||||
// logic.
|
||||
StringRef getMIPSABIDirSuffix() const { return GCCMIPSABIDirSuffix; }
|
||||
|
||||
/// \brief Get the detected GCC version string.
|
||||
const GCCVersion &getVersion() const { return Version; }
|
||||
|
@ -140,18 +140,15 @@ protected:
|
|||
SmallVectorImpl<StringRef> &BiarchLibDirs,
|
||||
SmallVectorImpl<StringRef> &BiarchTripleAliases);
|
||||
|
||||
void ScanLibDirForGCCTriple(const llvm::Triple &TargetArch,
|
||||
void ScanLibDirForGCCTriple(llvm::Triple::ArchType TargetArch,
|
||||
const llvm::opt::ArgList &Args,
|
||||
const std::string &LibDir,
|
||||
StringRef CandidateTriple,
|
||||
bool NeedsBiarchSuffix = false);
|
||||
|
||||
bool findMIPSMultilibs(const llvm::Triple &TargetArch, StringRef Path,
|
||||
const llvm::opt::ArgList &Args);
|
||||
|
||||
bool findBiarchMultilibs(const llvm::Triple &TargetArch, StringRef Path,
|
||||
const llvm::opt::ArgList &Args,
|
||||
bool NeedsBiarchSuffix);
|
||||
void findMIPSABIDirSuffix(std::string &Suffix,
|
||||
llvm::Triple::ArchType TargetArch, StringRef Path,
|
||||
const llvm::opt::ArgList &Args);
|
||||
};
|
||||
|
||||
GCCInstallationDetector GCCInstallation;
|
||||
|
@ -668,7 +665,9 @@ protected:
|
|||
|
||||
private:
|
||||
static bool addLibStdCXXIncludePaths(Twine Base, Twine Suffix,
|
||||
Twine TargetArchDir, Twine IncludeSuffix,
|
||||
Twine TargetArchDir,
|
||||
Twine BiarchSuffix,
|
||||
Twine MIPSABIDirSuffix,
|
||||
const llvm::opt::ArgList &DriverArgs,
|
||||
llvm::opt::ArgStringList &CC1Args);
|
||||
static bool addLibStdCXXIncludePaths(Twine Base, Twine TargetArchDir,
|
||||
|
|
|
@ -44,6 +44,11 @@ using namespace clang::driver::tools;
|
|||
using namespace clang;
|
||||
using namespace llvm::opt;
|
||||
|
||||
static bool hasMipsABIArg(const ArgList &Args, const char *Value) {
|
||||
Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
|
||||
return A && (A->getValue() == StringRef(Value));
|
||||
}
|
||||
|
||||
/// CheckPreprocessingOptions - Perform some validation of preprocessing
|
||||
/// arguments that is shared with gcc.
|
||||
static void CheckPreprocessingOptions(const Driver &D, const ArgList &Args) {
|
||||
|
@ -475,7 +480,7 @@ static bool isSignedCharDefault(const llvm::Triple &Triple) {
|
|||
case llvm::Triple::arm:
|
||||
case llvm::Triple::ppc:
|
||||
case llvm::Triple::ppc64:
|
||||
if (Triple.isOSDarwin())
|
||||
if (Triple.isOSBinFormatMachO())
|
||||
return true;
|
||||
return false;
|
||||
|
||||
|
@ -746,7 +751,7 @@ void Clang::AddARMTargetArgs(const ArgList &Args,
|
|||
const char *ABIName = 0;
|
||||
if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
|
||||
ABIName = A->getValue();
|
||||
} else if (Triple.isOSDarwin()) {
|
||||
} else if (Triple.isOSBinFormatMachO()) {
|
||||
// The backend is hardwired to assume AAPCS for M-class processors, ensure
|
||||
// the frontend matches that.
|
||||
if (Triple.getEnvironment() == llvm::Triple::EABI ||
|
||||
|
@ -1192,7 +1197,7 @@ static const char *getX86TargetCPU(const ArgList &Args,
|
|||
const llvm::Triple &Triple) {
|
||||
if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
|
||||
if (StringRef(A->getValue()) != "native") {
|
||||
if (Triple.isOSDarwin() && Triple.getArchName() == "x86_64h")
|
||||
if (Triple.isOSBinFormatMachO() && Triple.getArchName() == "x86_64h")
|
||||
return "core-avx2";
|
||||
|
||||
return A->getValue();
|
||||
|
@ -1217,7 +1222,7 @@ static const char *getX86TargetCPU(const ArgList &Args,
|
|||
bool Is64Bit = Triple.getArch() == llvm::Triple::x86_64;
|
||||
|
||||
// FIXME: Need target hooks.
|
||||
if (Triple.isOSDarwin()) {
|
||||
if (Triple.isOSBinFormatMachO()) {
|
||||
if (Triple.getArchName() == "x86_64h")
|
||||
return "core-avx2";
|
||||
return Is64Bit ? "core2" : "yonah";
|
||||
|
@ -2619,7 +2624,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
|||
// -gline-tables-only.
|
||||
CmdArgs.push_back("-gline-tables-only");
|
||||
// Default is dwarf-2 for darwin.
|
||||
if (getToolChain().getTriple().isOSDarwin())
|
||||
if (getToolChain().getTriple().isOSBinFormatMachO())
|
||||
CmdArgs.push_back("-gdwarf-2");
|
||||
} else if (A->getOption().matches(options::OPT_gdwarf_2))
|
||||
CmdArgs.push_back("-gdwarf-2");
|
||||
|
@ -2630,7 +2635,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
|||
else if (!A->getOption().matches(options::OPT_g0) &&
|
||||
!A->getOption().matches(options::OPT_ggdb0)) {
|
||||
// Default is dwarf-2 for darwin.
|
||||
if (getToolChain().getTriple().isOSDarwin())
|
||||
if (getToolChain().getTriple().isOSBinFormatMachO())
|
||||
CmdArgs.push_back("-gdwarf-2");
|
||||
else
|
||||
CmdArgs.push_back("-g");
|
||||
|
@ -3944,7 +3949,7 @@ ObjCRuntime Clang::AddObjCRuntimeArgs(const ArgList &args,
|
|||
// -fnext-runtime
|
||||
} else if (runtimeArg->getOption().matches(options::OPT_fnext_runtime)) {
|
||||
// On Darwin, make this use the default behavior for the toolchain.
|
||||
if (getToolChain().getTriple().isOSDarwin()) {
|
||||
if (getToolChain().getTriple().isOSBinFormatMachO()) {
|
||||
runtime = getToolChain().getDefaultObjCRuntime(isNonFragile);
|
||||
|
||||
// Otherwise, build for a generic macosx port.
|
||||
|
@ -4218,7 +4223,7 @@ void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA,
|
|||
|
||||
// If using a driver driver, force the arch.
|
||||
llvm::Triple::ArchType Arch = getToolChain().getArch();
|
||||
if (getToolChain().getTriple().isOSDarwin()) {
|
||||
if (getToolChain().getTriple().isOSBinFormatMachO()) {
|
||||
CmdArgs.push_back("-arch");
|
||||
|
||||
// FIXME: Remove these special cases.
|
||||
|
@ -4713,11 +4718,6 @@ const char *arm::getLLVMArchSuffixForARM(StringRef CPU) {
|
|||
.Default("");
|
||||
}
|
||||
|
||||
bool mips::hasMipsAbiArg(const ArgList &Args, const char *Value) {
|
||||
Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
|
||||
return A && (A->getValue() == StringRef(Value));
|
||||
}
|
||||
|
||||
llvm::Triple::ArchType darwin::getArchTypeForMachOArchName(StringRef Str) {
|
||||
// See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
|
||||
// archs which Darwin doesn't use.
|
||||
|
@ -6192,13 +6192,13 @@ void netbsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
|
|||
break;
|
||||
case llvm::Triple::mips64:
|
||||
case llvm::Triple::mips64el:
|
||||
if (mips::hasMipsAbiArg(Args, "32")) {
|
||||
if (hasMipsABIArg(Args, "32")) {
|
||||
CmdArgs.push_back("-m");
|
||||
if (getToolChain().getArch() == llvm::Triple::mips64)
|
||||
CmdArgs.push_back("elf32btsmip");
|
||||
else
|
||||
CmdArgs.push_back("elf32ltsmip");
|
||||
} else if (mips::hasMipsAbiArg(Args, "64")) {
|
||||
} else if (hasMipsABIArg(Args, "64")) {
|
||||
CmdArgs.push_back("-m");
|
||||
if (getToolChain().getArch() == llvm::Triple::mips64)
|
||||
CmdArgs.push_back("elf64btsmip");
|
||||
|
@ -6502,7 +6502,7 @@ static StringRef getLinuxDynamicLinker(const ArgList &Args,
|
|||
return "/lib/ld.so.1";
|
||||
else if (ToolChain.getArch() == llvm::Triple::mips64 ||
|
||||
ToolChain.getArch() == llvm::Triple::mips64el) {
|
||||
if (mips::hasMipsAbiArg(Args, "n32"))
|
||||
if (hasMipsABIArg(Args, "n32"))
|
||||
return "/lib32/ld.so.1";
|
||||
else
|
||||
return "/lib64/ld.so.1";
|
||||
|
@ -6585,13 +6585,13 @@ void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA,
|
|||
else if (ToolChain.getArch() == llvm::Triple::mipsel)
|
||||
CmdArgs.push_back("elf32ltsmip");
|
||||
else if (ToolChain.getArch() == llvm::Triple::mips64) {
|
||||
if (mips::hasMipsAbiArg(Args, "n32"))
|
||||
if (hasMipsABIArg(Args, "n32"))
|
||||
CmdArgs.push_back("elf32btsmipn32");
|
||||
else
|
||||
CmdArgs.push_back("elf64btsmip");
|
||||
}
|
||||
else if (ToolChain.getArch() == llvm::Triple::mips64el) {
|
||||
if (mips::hasMipsAbiArg(Args, "n32"))
|
||||
if (hasMipsABIArg(Args, "n32"))
|
||||
CmdArgs.push_back("elf32ltsmipn32");
|
||||
else
|
||||
CmdArgs.push_back("elf64ltsmip");
|
||||
|
|
|
@ -209,10 +209,6 @@ namespace arm {
|
|||
const char* getLLVMArchSuffixForARM(StringRef CPU);
|
||||
}
|
||||
|
||||
namespace mips {
|
||||
bool hasMipsAbiArg(const llvm::opt::ArgList &Args, const char *Value);
|
||||
}
|
||||
|
||||
namespace darwin {
|
||||
llvm::Triple::ArchType getArchTypeForMachOArchName(StringRef Str);
|
||||
void setTripleTypeForMachOArchName(llvm::Triple &T, StringRef Str);
|
||||
|
|
|
@ -11,7 +11,6 @@ endfunction()
|
|||
|
||||
add_subdirectory(Basic)
|
||||
add_subdirectory(Lex)
|
||||
add_subdirectory(Driver)
|
||||
if(CLANG_ENABLE_STATIC_ANALYZER)
|
||||
add_subdirectory(Frontend)
|
||||
endif()
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
set(LLVM_LINK_COMPONENTS
|
||||
Support
|
||||
)
|
||||
|
||||
add_clang_unittest(DriverTests
|
||||
MultilibTest.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(DriverTests
|
||||
clangDriver
|
||||
)
|
|
@ -1,16 +0,0 @@
|
|||
##===- unittests/Driver/Makefile ---------------------------*- Makefile -*-===##
|
||||
#
|
||||
# The LLVM Compiler Infrastructure
|
||||
#
|
||||
# This file is distributed under the University of Illinois Open Source
|
||||
# License. See LICENSE.TXT for details.
|
||||
#
|
||||
##===----------------------------------------------------------------------===##
|
||||
|
||||
CLANG_LEVEL = ../..
|
||||
TESTNAME = Multilib
|
||||
include $(CLANG_LEVEL)/../../Makefile.config
|
||||
LINK_COMPONENTS := $(TARGETS_TO_BUILD) support option
|
||||
USEDLIBS = clangDriver.a clangBasic.a
|
||||
|
||||
include $(CLANG_LEVEL)/unittests/Makefile
|
|
@ -1,356 +0,0 @@
|
|||
//===- unittests/Driver/MultilibTest.cpp --- Multilib tests ---------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Unit tests for Multilib and MultilibSet
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/Driver/Multilib.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "llvm/ADT/StringSwitch.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
|
||||
using namespace clang::driver;
|
||||
using namespace clang;
|
||||
|
||||
TEST(MultilibTest, MultilibValidity) {
|
||||
|
||||
ASSERT_TRUE(Multilib().isValid()) << "Empty multilib is not valid";
|
||||
|
||||
ASSERT_TRUE(Multilib().flag("+foo").isValid())
|
||||
<< "Single indicative flag is not valid";
|
||||
|
||||
ASSERT_TRUE(Multilib().flag("-foo").isValid())
|
||||
<< "Single contraindicative flag is not valid";
|
||||
|
||||
ASSERT_FALSE(Multilib().flag("+foo").flag("-foo").isValid())
|
||||
<< "Conflicting flags should invalidate the Multilib";
|
||||
|
||||
ASSERT_TRUE(Multilib().flag("+foo").flag("+foo").isValid())
|
||||
<< "Multilib should be valid even if it has the same flag twice";
|
||||
|
||||
ASSERT_TRUE(Multilib().flag("+foo").flag("-foobar").isValid())
|
||||
<< "Seemingly conflicting prefixes shouldn't actually conflict";
|
||||
}
|
||||
|
||||
TEST(MultilibTest, OpEqReflexivity1) {
|
||||
Multilib M;
|
||||
ASSERT_TRUE(M == M) << "Multilib::operator==() is not reflexive";
|
||||
}
|
||||
|
||||
TEST(MultilibTest, OpEqReflexivity2) {
|
||||
ASSERT_TRUE(Multilib() == Multilib())
|
||||
<< "Separately constructed default multilibs are not equal";
|
||||
}
|
||||
|
||||
TEST(MultilibTest, OpEqReflexivity3) {
|
||||
Multilib M1, M2;
|
||||
M1.flag("+foo");
|
||||
M2.flag("+foo");
|
||||
ASSERT_TRUE(M1 == M2) << "Multilibs with the same flag should be the same";
|
||||
}
|
||||
|
||||
TEST(MultilibTest, OpEqInequivalence1) {
|
||||
Multilib M1, M2;
|
||||
M1.flag("+foo");
|
||||
M2.flag("-foo");
|
||||
ASSERT_FALSE(M1 == M2) << "Multilibs with conflicting flags are not the same";
|
||||
ASSERT_FALSE(M2 == M1)
|
||||
<< "Multilibs with conflicting flags are not the same (commuted)";
|
||||
}
|
||||
|
||||
TEST(MultilibTest, OpEqInequivalence2) {
|
||||
Multilib M1, M2;
|
||||
M2.flag("+foo");
|
||||
ASSERT_FALSE(M1 == M2) << "Flags make Multilibs different";
|
||||
}
|
||||
|
||||
TEST(MultilibTest, OpEqEquivalence1) {
|
||||
Multilib M1, M2;
|
||||
M1.flag("+foo");
|
||||
M2.flag("+foo").flag("+foo");
|
||||
ASSERT_TRUE(M1 == M2) << "Flag duplication shouldn't affect equivalence";
|
||||
ASSERT_TRUE(M2 == M1)
|
||||
<< "Flag duplication shouldn't affect equivalence (commuted)";
|
||||
}
|
||||
|
||||
TEST(MultilibTest, OpEqEquivalence2) {
|
||||
Multilib M1("64");
|
||||
Multilib M2;
|
||||
M2.gccSuffix("/64");
|
||||
ASSERT_TRUE(M1 == M2)
|
||||
<< "Constructor argument must match Multilib::gccSuffix()";
|
||||
ASSERT_TRUE(M2 == M1)
|
||||
<< "Constructor argument must match Multilib::gccSuffix() (commuted)";
|
||||
}
|
||||
|
||||
TEST(MultilibTest, OpEqEquivalence3) {
|
||||
Multilib M1("", "32");
|
||||
Multilib M2;
|
||||
M2.osSuffix("/32");
|
||||
ASSERT_TRUE(M1 == M2)
|
||||
<< "Constructor argument must match Multilib::osSuffix()";
|
||||
ASSERT_TRUE(M2 == M1)
|
||||
<< "Constructor argument must match Multilib::osSuffix() (commuted)";
|
||||
}
|
||||
|
||||
TEST(MultilibTest, OpEqEquivalence4) {
|
||||
Multilib M1("", "", "16");
|
||||
Multilib M2;
|
||||
M2.includeSuffix("/16");
|
||||
ASSERT_TRUE(M1 == M2)
|
||||
<< "Constructor argument must match Multilib::includeSuffix()";
|
||||
ASSERT_TRUE(M2 == M1)
|
||||
<< "Constructor argument must match Multilib::includeSuffix() (commuted)";
|
||||
}
|
||||
|
||||
TEST(MultilibTest, OpEqInequivalence3) {
|
||||
Multilib M1("foo");
|
||||
Multilib M2("bar");
|
||||
ASSERT_FALSE(M1 == M2) << "Differing gccSuffixes should be different";
|
||||
ASSERT_FALSE(M2 == M1)
|
||||
<< "Differing gccSuffixes should be different (commuted)";
|
||||
}
|
||||
|
||||
TEST(MultilibTest, OpEqInequivalence4) {
|
||||
Multilib M1("", "foo");
|
||||
Multilib M2("", "bar");
|
||||
ASSERT_FALSE(M1 == M2) << "Differing osSuffixes should be different";
|
||||
ASSERT_FALSE(M2 == M1)
|
||||
<< "Differing osSuffixes should be different (commuted)";
|
||||
}
|
||||
|
||||
TEST(MultilibTest, OpEqInequivalence5) {
|
||||
Multilib M1("", "", "foo");
|
||||
Multilib M2("", "", "bar");
|
||||
ASSERT_FALSE(M1 == M2) << "Differing includeSuffixes should be different";
|
||||
ASSERT_FALSE(M2 == M1)
|
||||
<< "Differing includeSuffixes should be different (commuted)";
|
||||
}
|
||||
|
||||
TEST(MultilibTest, Construction1) {
|
||||
Multilib M("gcc64", "os64", "inc64");
|
||||
ASSERT_TRUE(M.gccSuffix() == "/gcc64");
|
||||
ASSERT_TRUE(M.osSuffix() == "/os64");
|
||||
ASSERT_TRUE(M.includeSuffix() == "/inc64");
|
||||
}
|
||||
|
||||
TEST(MultilibTest, Construction2) {
|
||||
Multilib M1;
|
||||
Multilib M2("");
|
||||
Multilib M3("", "");
|
||||
Multilib M4("", "", "");
|
||||
ASSERT_TRUE(M1 == M2)
|
||||
<< "Default arguments to Multilib constructor broken (first argument)";
|
||||
ASSERT_TRUE(M1 == M3)
|
||||
<< "Default arguments to Multilib constructor broken (second argument)";
|
||||
ASSERT_TRUE(M1 == M4)
|
||||
<< "Default arguments to Multilib constructor broken (third argument)";
|
||||
}
|
||||
|
||||
TEST(MultilibTest, Construction3) {
|
||||
Multilib M = Multilib().flag("+f1").flag("+f2").flag("-f3");
|
||||
for (Multilib::flags_list::const_iterator I = M.flags().begin(),
|
||||
E = M.flags().end();
|
||||
I != E; ++I) {
|
||||
ASSERT_TRUE(llvm::StringSwitch<bool>(*I)
|
||||
.Cases("+f1", "+f2", "-f3", true)
|
||||
.Default(false));
|
||||
}
|
||||
}
|
||||
|
||||
static bool hasFlag(const Multilib &M, StringRef Flag) {
|
||||
for (Multilib::flags_list::const_iterator I = M.flags().begin(),
|
||||
E = M.flags().end();
|
||||
I != E; ++I) {
|
||||
if (*I == Flag)
|
||||
return true;
|
||||
else if (StringRef(*I).substr(1) == Flag.substr(1))
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
TEST(MultilibTest, SetConstruction1) {
|
||||
// Single maybe
|
||||
MultilibSet MS;
|
||||
ASSERT_TRUE(MS.size() == 0);
|
||||
MS.Maybe(Multilib("64").flag("+m64"));
|
||||
ASSERT_TRUE(MS.size() == 2);
|
||||
for (MultilibSet::const_iterator I = MS.begin(), E = MS.end(); I != E; ++I) {
|
||||
if (I->gccSuffix() == "/64")
|
||||
ASSERT_TRUE(I->flags()[0] == "+m64");
|
||||
else if (I->gccSuffix() == "")
|
||||
ASSERT_TRUE(I->flags()[0] == "-m64");
|
||||
else
|
||||
FAIL() << "Unrecognized gccSufix: " << I->gccSuffix();
|
||||
}
|
||||
}
|
||||
|
||||
TEST(MultilibTest, SetConstruction2) {
|
||||
// Double maybe
|
||||
MultilibSet MS;
|
||||
MS.Maybe(Multilib("sof").flag("+sof"));
|
||||
MS.Maybe(Multilib("el").flag("+EL"));
|
||||
ASSERT_TRUE(MS.size() == 4);
|
||||
for (MultilibSet::const_iterator I = MS.begin(), E = MS.end(); I != E; ++I) {
|
||||
ASSERT_TRUE(I->isValid()) << "Multilb " << *I << " should be valid";
|
||||
ASSERT_TRUE(llvm::StringSwitch<bool>(I->gccSuffix())
|
||||
.Cases("", "/sof", "/el", "/sof/el", true)
|
||||
.Default(false))
|
||||
<< "Multilib " << *I << " wasn't expected";
|
||||
ASSERT_TRUE(llvm::StringSwitch<bool>(I->gccSuffix())
|
||||
.Case("", hasFlag(*I, "-sof"))
|
||||
.Case("/sof", hasFlag(*I, "+sof"))
|
||||
.Case("/el", hasFlag(*I, "-sof"))
|
||||
.Case("/sof/el", hasFlag(*I, "+sof"))
|
||||
.Default(false))
|
||||
<< "Multilib " << *I << " didn't have the appropriate {+,-}sof flag";
|
||||
ASSERT_TRUE(llvm::StringSwitch<bool>(I->gccSuffix())
|
||||
.Case("", hasFlag(*I, "-EL"))
|
||||
.Case("/sof", hasFlag(*I, "-EL"))
|
||||
.Case("/el", hasFlag(*I, "+EL"))
|
||||
.Case("/sof/el", hasFlag(*I, "+EL"))
|
||||
.Default(false))
|
||||
<< "Multilib " << *I << " didn't have the appropriate {+,-}EL flag";
|
||||
}
|
||||
}
|
||||
|
||||
TEST(MultilibTest, SetPushback) {
|
||||
MultilibSet MS;
|
||||
MS.push_back(Multilib("one"));
|
||||
MS.push_back(Multilib("two"));
|
||||
ASSERT_TRUE(MS.size() == 2);
|
||||
for (MultilibSet::const_iterator I = MS.begin(), E = MS.end(); I != E; ++I) {
|
||||
ASSERT_TRUE(llvm::StringSwitch<bool>(I->gccSuffix())
|
||||
.Cases("/one", "/two", true)
|
||||
.Default(false));
|
||||
}
|
||||
MS.clear();
|
||||
ASSERT_TRUE(MS.size() == 0);
|
||||
}
|
||||
|
||||
TEST(MultilibTest, SetRegexFilter) {
|
||||
MultilibSet MS;
|
||||
MS.Maybe(Multilib("one"));
|
||||
MS.Maybe(Multilib("two"));
|
||||
MS.Maybe(Multilib("three"));
|
||||
ASSERT_EQ(MS.size(), (unsigned)2 * 2 * 2)
|
||||
<< "Size before filter was incorrect. Contents:\n" << MS;
|
||||
MS.FilterOut("/one/two/three");
|
||||
ASSERT_EQ(MS.size(), (unsigned)2 * 2 * 2 - 1)
|
||||
<< "Size after filter was incorrect. Contents:\n" << MS;
|
||||
for (MultilibSet::const_iterator I = MS.begin(), E = MS.end(); I != E; ++I) {
|
||||
ASSERT_TRUE(I->gccSuffix() != "/one/two/three")
|
||||
<< "The filter should have removed " << *I;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(MultilibTest, SetFilterObject) {
|
||||
// Filter object
|
||||
struct StartsWithP : public MultilibSet::FilterCallback {
|
||||
bool operator()(const Multilib &M) const LLVM_OVERRIDE {
|
||||
return StringRef(M.gccSuffix()).startswith("/p");
|
||||
}
|
||||
};
|
||||
MultilibSet MS;
|
||||
MS.Maybe(Multilib("orange"));
|
||||
MS.Maybe(Multilib("pear"));
|
||||
MS.Maybe(Multilib("plum"));
|
||||
ASSERT_EQ((int)MS.size(), 1 /* Default */ +
|
||||
1 /* pear */ +
|
||||
1 /* plum */ +
|
||||
1 /* pear/plum */ +
|
||||
1 /* orange */ +
|
||||
1 /* orange/pear */ +
|
||||
1 /* orange/plum */ +
|
||||
1 /* orange/pear/plum */ )
|
||||
<< "Size before filter was incorrect. Contents:\n" << MS;
|
||||
MS.FilterOut(StartsWithP());
|
||||
ASSERT_EQ((int)MS.size(), 1 /* Default */ +
|
||||
1 /* orange */ +
|
||||
1 /* orange/pear */ +
|
||||
1 /* orange/plum */ +
|
||||
1 /* orange/pear/plum */ )
|
||||
<< "Size after filter was incorrect. Contents:\n" << MS;
|
||||
for (MultilibSet::const_iterator I = MS.begin(), E = MS.end(); I != E; ++I) {
|
||||
ASSERT_FALSE(StringRef(I->gccSuffix()).startswith("/p"))
|
||||
<< "The filter should have removed " << *I;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(MultilibTest, SetSelection1) {
|
||||
MultilibSet MS1 = MultilibSet()
|
||||
.Maybe(Multilib("64").flag("+m64"));
|
||||
|
||||
Multilib::flags_list FlagM64;
|
||||
FlagM64.push_back("+m64");
|
||||
Multilib SelectionM64;
|
||||
ASSERT_TRUE(MS1.select(FlagM64, SelectionM64))
|
||||
<< "Flag set was {\"+m64\"}, but selection not found";
|
||||
ASSERT_TRUE(SelectionM64.gccSuffix() == "/64")
|
||||
<< "Selection picked " << SelectionM64 << " which was not expected";
|
||||
|
||||
Multilib::flags_list FlagNoM64;
|
||||
FlagNoM64.push_back("-m64");
|
||||
Multilib SelectionNoM64;
|
||||
ASSERT_TRUE(MS1.select(FlagNoM64, SelectionNoM64))
|
||||
<< "Flag set was {\"-m64\"}, but selection not found";
|
||||
ASSERT_TRUE(SelectionNoM64.gccSuffix() == "")
|
||||
<< "Selection picked " << SelectionNoM64 << " which was not expected";
|
||||
}
|
||||
|
||||
TEST(MultilibTest, SetSelection2) {
|
||||
MultilibSet MS2 = MultilibSet()
|
||||
.Maybe(Multilib("el").flag("+EL"))
|
||||
.Maybe(Multilib("sf").flag("+SF"));
|
||||
|
||||
for (unsigned I = 0; I < 4; ++I) {
|
||||
bool IsEL = I & 0x1;
|
||||
bool IsSF = I & 0x2;
|
||||
Multilib::flags_list Flags;
|
||||
if (IsEL)
|
||||
Flags.push_back("+EL");
|
||||
else
|
||||
Flags.push_back("-EL");
|
||||
|
||||
if (IsSF)
|
||||
Flags.push_back("+SF");
|
||||
else
|
||||
Flags.push_back("-SF");
|
||||
|
||||
Multilib Selection;
|
||||
ASSERT_TRUE(MS2.select(Flags, Selection)) << "Selection failed for "
|
||||
<< (IsEL ? "+EL" : "-EL") << " "
|
||||
<< (IsSF ? "+SF" : "-SF");
|
||||
|
||||
std::string Suffix;
|
||||
if (IsEL)
|
||||
Suffix += "/el";
|
||||
if (IsSF)
|
||||
Suffix += "/sf";
|
||||
|
||||
ASSERT_EQ(Selection.gccSuffix(), Suffix) << "Selection picked " << Selection
|
||||
<< " which was not expected ";
|
||||
}
|
||||
}
|
||||
|
||||
TEST(MultilibTest, SetCombineWith) {
|
||||
MultilibSet Coffee;
|
||||
Coffee.push_back(Multilib("coffee"));
|
||||
MultilibSet Milk;
|
||||
Milk.push_back(Multilib("milk"));
|
||||
MultilibSet Latte;
|
||||
ASSERT_EQ(Latte.size(), (unsigned)0);
|
||||
Latte.combineWith(Coffee);
|
||||
ASSERT_EQ(Latte.size(), (unsigned)1);
|
||||
Latte.combineWith(Milk);
|
||||
ASSERT_EQ(Latte.size(), (unsigned)2);
|
||||
}
|
|
@ -14,7 +14,7 @@ ifndef CLANG_LEVEL
|
|||
|
||||
IS_UNITTEST_LEVEL := 1
|
||||
CLANG_LEVEL := ..
|
||||
PARALLEL_DIRS = Basic Lex Driver
|
||||
PARALLEL_DIRS = Basic Lex
|
||||
|
||||
include $(CLANG_LEVEL)/../..//Makefile.config
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче