diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Linker/LinkModules.cpp | 40 |
1 files changed, 33 insertions, 7 deletions
diff --git a/llvm/lib/Linker/LinkModules.cpp b/llvm/lib/Linker/LinkModules.cpp index dc002d8..9585fba 100644 --- a/llvm/lib/Linker/LinkModules.cpp +++ b/llvm/lib/Linker/LinkModules.cpp @@ -18,6 +18,7 @@ #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/Statistic.h" +#include "llvm/ADT/Triple.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DebugInfo.h" #include "llvm/IR/DiagnosticInfo.h" @@ -1457,6 +1458,28 @@ bool ModuleLinker::linkModuleFlagsMetadata() { return HasErr; } +// This function returns true if the triples match. +static bool triplesMatch(const Triple &T0, const Triple &T1) { + // If vendor is apple, ignore the version number. + if (T0.getVendor() == Triple::Apple) + return T0.getArch() == T1.getArch() && + T0.getSubArch() == T1.getSubArch() && + T0.getVendor() == T1.getVendor() && + T0.getOS() == T1.getOS(); + + return T0 == T1; +} + +// This function returns the merged triple. +static std::string mergeTriples(const Triple &SrcTriple, const Triple &DstTriple) { + // If vendor is apple, pick the triple with the larger version number. + if (SrcTriple.getVendor() == Triple::Apple) + if (DstTriple.isOSVersionLT(SrcTriple)) + return SrcTriple.str(); + + return DstTriple.str(); +} + bool ModuleLinker::run() { assert(DstM && "Null destination module"); assert(SrcM && "Null source module"); @@ -1466,10 +1489,6 @@ bool ModuleLinker::run() { if (!DstM->getDataLayout() && SrcM->getDataLayout()) DstM->setDataLayout(SrcM->getDataLayout()); - // Copy the target triple from the source to dest if the dest's is empty. - if (DstM->getTargetTriple().empty() && !SrcM->getTargetTriple().empty()) - DstM->setTargetTriple(SrcM->getTargetTriple()); - if (SrcM->getDataLayout() && DstM->getDataLayout() && *SrcM->getDataLayout() != *DstM->getDataLayout()) { emitWarning("Linking two modules of different data layouts: '" + @@ -1478,14 +1497,21 @@ bool ModuleLinker::run() { DstM->getModuleIdentifier() + "' is '" + DstM->getDataLayoutStr() + "'\n"); } - if (!SrcM->getTargetTriple().empty() && - DstM->getTargetTriple() != SrcM->getTargetTriple()) { + + // Copy the target triple from the source to dest if the dest's is empty. + if (DstM->getTargetTriple().empty() && !SrcM->getTargetTriple().empty()) + DstM->setTargetTriple(SrcM->getTargetTriple()); + + Triple SrcTriple(SrcM->getTargetTriple()), DstTriple(DstM->getTargetTriple()); + + if (!SrcM->getTargetTriple().empty() && !triplesMatch(SrcTriple, DstTriple)) emitWarning("Linking two modules of different target triples: " + SrcM->getModuleIdentifier() + "' is '" + SrcM->getTargetTriple() + "' whereas '" + DstM->getModuleIdentifier() + "' is '" + DstM->getTargetTriple() + "'\n"); - } + + DstM->setTargetTriple(mergeTriples(SrcTriple, DstTriple)); // Append the module inline asm string. if (!SrcM->getModuleInlineAsm().empty()) { |