- Patch by Jonathan Gray!


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74453 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Daniel Dunbar 2009-06-29 20:52:51 +00:00
Родитель 3708b3df2e
Коммит f7b8eec37c
9 изменённых файлов: 296 добавлений и 0 удалений

Просмотреть файл

@ -69,6 +69,8 @@ public:
const HostInfo *createDarwinHostInfo(const Driver &D,
const llvm::Triple& Triple);
const HostInfo *createOpenBSDHostInfo(const Driver &D,
const llvm::Triple& Triple);
const HostInfo *createFreeBSDHostInfo(const Driver &D,
const llvm::Triple& Triple);
const HostInfo *createDragonFlyHostInfo(const Driver &D,

Просмотреть файл

@ -70,6 +70,19 @@ static void getSolarisDefines(const LangOptions &Opts, std::vector<char> &Defs)
Define(Defs, "__SVR4");
}
static void getOpenBSDDefines(const LangOptions &Opts, bool is64Bit,
const char *Triple, std::vector<char> &Defs) {
// OpenBSD defines; list based off of gcc output
Define(Defs, "__OpenBSD__", "1");
Define(Defs, "__KPRINTF_ATTRIBUTE__");
DefineStd(Defs, "unix", Opts);
Define(Defs, "__ELF__", "1");
if (is64Bit) {
Define(Defs, "__LP64__");
}
}
static void getFreeBSDDefines(const LangOptions &Opts, bool is64Bit,
const char *Triple, std::vector<char> &Defs) {
// FreeBSD defines; list based off of gcc output
@ -865,6 +878,20 @@ public:
};
} // end anonymous namespace
namespace {
// x86-32 OpenBSD target
class OpenBSDX86_32TargetInfo : public X86_32TargetInfo {
public:
OpenBSDX86_32TargetInfo(const std::string& triple) :
X86_32TargetInfo(triple) { }
virtual void getTargetDefines(const LangOptions &Opts,
std::vector<char> &Defines) const {
X86_32TargetInfo::getTargetDefines(Opts, Defines);
getOpenBSDDefines(Opts, 0, getTargetTriple(), Defines);
}
};
} // end anonymous namespace
namespace {
// x86-32 FreeBSD target
class FreeBSDX86_32TargetInfo : public X86_32TargetInfo {
@ -986,6 +1013,20 @@ public:
};
} // end anonymous namespace
namespace {
// x86-64 OpenBSD target
class OpenBSDX86_64TargetInfo : public X86_64TargetInfo {
public:
OpenBSDX86_64TargetInfo(const std::string &triple)
: X86_64TargetInfo(triple) {}
virtual void getTargetDefines(const LangOptions &Opts,
std::vector<char> &Defines) const {
X86_64TargetInfo::getTargetDefines(Opts, Defines);
getOpenBSDDefines(Opts, 1, getTargetTriple(), Defines);
}
};
} // end anonymous namespace
namespace {
// x86-64 FreeBSD target
class FreeBSDX86_64TargetInfo : public X86_64TargetInfo {
@ -1457,6 +1498,7 @@ TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) {
// Additions and corrections are welcome.
bool isDarwin = T.find("-darwin") != std::string::npos;
bool isDragonFly = T.find("-dragonfly") != std::string::npos;
bool isOpenBSD = T.find("-openbsd") != std::string::npos;
bool isFreeBSD = T.find("-freebsd") != std::string::npos;
bool isSolaris = T.find("-solaris") != std::string::npos;
bool isLinux = T.find("-linux") != std::string::npos;
@ -1495,6 +1537,8 @@ TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) {
return new DarwinX86_64TargetInfo(T);
if (isLinux)
return new LinuxX86_64TargetInfo(T);
if (isOpenBSD)
return new OpenBSDX86_64TargetInfo(T);
if (isFreeBSD)
return new FreeBSDX86_64TargetInfo(T);
if (isSolaris)
@ -1515,6 +1559,8 @@ TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) {
return new LinuxX86_32TargetInfo(T);
if (isDragonFly)
return new DragonFlyX86_32TargetInfo(T);
if (isOpenBSD)
return new OpenBSDX86_32TargetInfo(T);
if (isFreeBSD)
return new FreeBSDX86_32TargetInfo(T);
if (isSolaris)

Просмотреть файл

@ -1205,6 +1205,8 @@ const HostInfo *Driver::GetHostInfo(const char *TripleStr) const {
return createDarwinHostInfo(*this, Triple);
case llvm::Triple::DragonFly:
return createDragonFlyHostInfo(*this, Triple);
case llvm::Triple::OpenBSD:
return createOpenBSDHostInfo(*this, Triple);
case llvm::Triple::FreeBSD:
return createFreeBSDHostInfo(*this, Triple);
case llvm::Triple::Linux:

Просмотреть файл

@ -234,6 +234,57 @@ ToolChain *UnknownHostInfo::getToolChain(const ArgList &Args,
return TC;
}
// OpenBSD Host Info
/// OpenBSDHostInfo - OpenBSD host information implementation.
class OpenBSDHostInfo : public HostInfo {
/// Cache of tool chains we have created.
mutable llvm::StringMap<ToolChain*> ToolChains;
public:
OpenBSDHostInfo(const Driver &D, const llvm::Triple& Triple)
: HostInfo(D, Triple) {}
~OpenBSDHostInfo();
virtual bool useDriverDriver() const;
virtual types::ID lookupTypeForExtension(const char *Ext) const {
return types::lookupTypeForExtension(Ext);
}
virtual ToolChain *getToolChain(const ArgList &Args,
const char *ArchName) const;
};
OpenBSDHostInfo::~OpenBSDHostInfo() {
for (llvm::StringMap<ToolChain*>::iterator
it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
delete it->second;
}
bool OpenBSDHostInfo::useDriverDriver() const {
return false;
}
ToolChain *OpenBSDHostInfo::getToolChain(const ArgList &Args,
const char *ArchName) const {
assert(!ArchName &&
"Unexpected arch name on platform without driver driver support.");
std::string Arch = getArchName();
ArchName = Arch.c_str();
ToolChain *&TC = ToolChains[ArchName];
if (!TC) {
llvm::Triple TCTriple(getTriple());
TCTriple.setArchName(ArchName);
TC = new toolchains::OpenBSD(*this, TCTriple);
}
return TC;
}
// FreeBSD Host Info
/// FreeBSDHostInfo - FreeBSD host information implementation.
@ -416,6 +467,12 @@ clang::driver::createDarwinHostInfo(const Driver &D,
return new DarwinHostInfo(D, Triple);
}
const HostInfo *
clang::driver::createOpenBSDHostInfo(const Driver &D,
const llvm::Triple& Triple) {
return new OpenBSDHostInfo(D, Triple);
}
const HostInfo *
clang::driver::createFreeBSDHostInfo(const Driver &D,
const llvm::Triple& Triple) {

Просмотреть файл

@ -384,6 +384,36 @@ DerivedArgList *Generic_GCC::TranslateArgs(InputArgList &Args) const {
return new DerivedArgList(Args, true);
}
/// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly.
OpenBSD::OpenBSD(const HostInfo &Host, const llvm::Triple& Triple)
: Generic_GCC(Host, Triple) {
getFilePaths().push_back(getHost().getDriver().Dir + "/../lib");
getFilePaths().push_back("/usr/lib");
}
Tool &OpenBSD::SelectTool(const Compilation &C, const JobAction &JA) const {
Action::ActionClass Key;
if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getArchName()))
Key = Action::AnalyzeJobClass;
else
Key = JA.getKind();
Tool *&T = Tools[Key];
if (!T) {
switch (Key) {
case Action::AssembleJobClass:
T = new tools::openbsd::Assemble(*this); break;
case Action::LinkJobClass:
T = new tools::openbsd::Link(*this); break;
default:
T = &Generic_GCC::SelectTool(C, JA);
}
}
return *T;
}
/// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly.
FreeBSD::FreeBSD(const HostInfo &Host, const llvm::Triple& Triple, bool Lib32)

Просмотреть файл

@ -107,6 +107,13 @@ public:
virtual const char *GetDefaultRelocationModel() const { return "pic"; }
};
class VISIBILITY_HIDDEN OpenBSD : public Generic_GCC {
public:
OpenBSD(const HostInfo &Host, const llvm::Triple& Triple);
virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
};
class VISIBILITY_HIDDEN FreeBSD : public Generic_GCC {
public:
FreeBSD(const HostInfo &Host, const llvm::Triple& Triple, bool Lib32);

Просмотреть файл

@ -1759,6 +1759,118 @@ void darwin::Lipo::ConstructJob(Compilation &C, const JobAction &JA,
Dest.addCommand(new Command(Exec, CmdArgs));
}
void openbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
Job &Dest, const InputInfo &Output,
const InputInfoList &Inputs,
const ArgList &Args,
const char *LinkingOutput) const
{
ArgStringList CmdArgs;
Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
options::OPT_Xassembler);
CmdArgs.push_back("-o");
if (Output.isPipe())
CmdArgs.push_back("-");
else
CmdArgs.push_back(Output.getFilename());
for (InputInfoList::const_iterator
it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
const InputInfo &II = *it;
if (II.isPipe())
CmdArgs.push_back("-");
else
CmdArgs.push_back(II.getFilename());
}
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath(C, "as").c_str());
Dest.addCommand(new Command(Exec, CmdArgs));
}
void openbsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
Job &Dest, const InputInfo &Output,
const InputInfoList &Inputs,
const ArgList &Args,
const char *LinkingOutput) const {
const Driver &D = getToolChain().getHost().getDriver();
ArgStringList CmdArgs;
if (Args.hasArg(options::OPT_static)) {
CmdArgs.push_back("-Bstatic");
} else {
CmdArgs.push_back("--eh-frame-hdr");
if (Args.hasArg(options::OPT_shared)) {
CmdArgs.push_back("-Bshareable");
} else {
CmdArgs.push_back("-dynamic-linker");
CmdArgs.push_back("/usr/libexec/ld.so");
}
}
if (Output.isPipe()) {
CmdArgs.push_back("-o");
CmdArgs.push_back("-");
} else if (Output.isFilename()) {
CmdArgs.push_back("-o");
CmdArgs.push_back(Output.getFilename());
} else {
assert(Output.isNothing() && "Invalid output.");
}
if (!Args.hasArg(options::OPT_nostdlib) &&
!Args.hasArg(options::OPT_nostartfiles)) {
if (!Args.hasArg(options::OPT_shared)) {
CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crt0.o").c_str()));
CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbegin.o").c_str()));
} else {
CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbeginS.o").c_str()));
}
}
Args.AddAllArgs(CmdArgs, options::OPT_L);
Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
Args.AddAllArgs(CmdArgs, options::OPT_e);
for (InputInfoList::const_iterator
it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
const InputInfo &II = *it;
// Don't try to pass LLVM inputs to a generic gcc.
if (II.getType() == types::TY_LLVMBC)
D.Diag(clang::diag::err_drv_no_linker_llvm_support)
<< getToolChain().getTripleString().c_str();
if (II.isPipe())
CmdArgs.push_back("-");
else if (II.isFilename())
CmdArgs.push_back(II.getFilename());
else
II.getInputArg().renderAsInput(Args, CmdArgs);
}
if (!Args.hasArg(options::OPT_nostdlib) &&
!Args.hasArg(options::OPT_nodefaultlibs)) {
if (Args.hasArg(options::OPT_pthread))
CmdArgs.push_back("-pthread");
CmdArgs.push_back("-lc");
}
if (!Args.hasArg(options::OPT_nostdlib) &&
!Args.hasArg(options::OPT_nostartfiles)) {
if (!Args.hasArg(options::OPT_shared))
CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtend.o").c_str()));
else
CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtendS.o").c_str()));
}
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath(C, "ld").c_str());
Dest.addCommand(new Command(Exec, CmdArgs));
}
void freebsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
Job &Dest, const InputInfo &Output,

Просмотреть файл

@ -241,6 +241,40 @@ namespace darwin {
};
}
/// openbsd -- Directly call GNU Binutils assembler and linker
namespace openbsd {
class VISIBILITY_HIDDEN Assemble : public Tool {
public:
Assemble(const ToolChain &TC) : Tool("openbsd::Assemble", TC) {}
virtual bool acceptsPipedInput() const { return true; }
virtual bool canPipeOutput() const { return true; }
virtual bool hasIntegratedCPP() const { return false; }
virtual void ConstructJob(Compilation &C, const JobAction &JA,
Job &Dest,
const InputInfo &Output,
const InputInfoList &Inputs,
const ArgList &TCArgs,
const char *LinkingOutput) const;
};
class VISIBILITY_HIDDEN Link : public Tool {
public:
Link(const ToolChain &TC) : Tool("openbsd::Link", TC) {}
virtual bool acceptsPipedInput() const { return true; }
virtual bool canPipeOutput() const { return true; }
virtual bool hasIntegratedCPP() const { return false; }
virtual void ConstructJob(Compilation &C, const JobAction &JA,
Job &Dest,
const InputInfo &Output,
const InputInfoList &Inputs,
const ArgList &TCArgs,
const char *LinkingOutput) const;
};
}
/// freebsd -- Directly call GNU Binutils assembler and linker
namespace freebsd {
class VISIBILITY_HIDDEN Assemble : public Tool {

6
test/Driver/openbsd.c Normal file
Просмотреть файл

@ -0,0 +1,6 @@
// RUN: clang -ccc-clang-archs "" -ccc-host-triple i686-pc-openbsd %s -### 2> %t.log &&
// RUN: grep 'clang-cc" "-triple" "i386-pc-openbsd"' %t.log &&
// RUN: grep 'as" "-o" ".*\.o" ".*\.s' %t.log &&
// RUN: grep 'ld" "--eh-frame-hdr" "-dynamic-linker" ".*ld.so" "-o" "a\.out" ".*crt0.o" ".*crtbegin.o" ".*\.o" "-lc" ".*crtend.o"' %t.log &&
// RUN: true