summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSaleem Abdulrasool <compnerd@compnerd.org>2014-03-06 20:47:11 +0000
committerSaleem Abdulrasool <compnerd@compnerd.org>2014-03-06 20:47:11 +0000
commit4eb048a6f1b9777d31d71684204deb1b39aa1795 (patch)
tree956cabeaa8603c93307b2cff38b51e12fa34af78
parent5219b0f586e901b0aee7c927d97cf6d43f8fc49d (diff)
downloadllvm-4eb048a6f1b9777d31d71684204deb1b39aa1795.tar.gz
llvm-4eb048a6f1b9777d31d71684204deb1b39aa1795.tar.bz2
llvm-4eb048a6f1b9777d31d71684204deb1b39aa1795.tar.xz
Support: split object format out of environment
This is a preliminary setup change to support a renaming of Windows target triples. Split the object file format information out of the environment into a separate entity. Unfortunately, file format was previously treated as an environment with an unknown OS. This is most obvious in the ARM subtarget where the handling for macho on an arbitrary platform switches to AAPCS rather than APCS (as per Apple's needs). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@203160 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/ADT/Triple.h27
-rw-r--r--lib/MC/MCObjectFileInfo.cpp4
-rw-r--r--lib/Support/Triple.cpp52
-rw-r--r--lib/Target/ARM/ARMSubtarget.cpp5
-rw-r--r--lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp4
-rw-r--r--lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp4
-rw-r--r--tools/llvm-jitlistener/llvm-jitlistener.cpp4
-rw-r--r--tools/llvm-objdump/llvm-objdump.cpp2
-rw-r--r--unittests/ADT/TripleTest.cpp20
9 files changed, 96 insertions, 26 deletions
diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h
index 9238f5af7a..0eb0420f56 100644
--- a/include/llvm/ADT/Triple.h
+++ b/include/llvm/ADT/Triple.h
@@ -124,9 +124,14 @@ public:
CODE16,
EABI,
EABIHF,
- MachO,
Android,
- ELF
+ };
+ enum ObjectFormatType {
+ UnknownObjectFormat,
+
+ COFF,
+ ELF,
+ MachO,
};
private:
@@ -144,13 +149,16 @@ private:
/// The parsed Environment type.
EnvironmentType Environment;
+ /// The object format type.
+ ObjectFormatType ObjectFormat;
+
public:
/// @name Constructors
/// @{
/// \brief Default constructor is the same as an empty string and leaves all
/// triple fields unknown.
- Triple() : Data(), Arch(), Vendor(), OS(), Environment() {}
+ Triple() : Data(), Arch(), Vendor(), OS(), Environment(), ObjectFormat() {}
explicit Triple(const Twine &Str);
Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr);
@@ -189,6 +197,9 @@ public:
/// getEnvironment - Get the parsed environment type of this triple.
EnvironmentType getEnvironment() const { return Environment; }
+ /// getFormat - Get the object format for this triple.
+ ObjectFormatType getObjectFormat() const { return ObjectFormat; }
+
/// getOSVersion - Parse the version number from the OS name component of the
/// triple, if present.
///
@@ -344,18 +355,17 @@ public:
/// \brief Tests whether the OS uses the ELF binary format.
bool isOSBinFormatELF() const {
- return !isOSBinFormatMachO() && !isOSBinFormatCOFF();
+ return getObjectFormat() == Triple::ELF;
}
/// \brief Tests whether the OS uses the COFF binary format.
bool isOSBinFormatCOFF() const {
- return getEnvironment() != Triple::ELF &&
- getEnvironment() != Triple::MachO && isOSWindows();
+ return getObjectFormat() == Triple::COFF;
}
/// \brief Tests whether the environment is MachO.
bool isOSBinFormatMachO() const {
- return getEnvironment() == Triple::MachO || isOSDarwin();
+ return getObjectFormat() == Triple::MachO;
}
/// @}
@@ -378,6 +388,9 @@ public:
/// to a known type.
void setEnvironment(EnvironmentType Kind);
+ /// setObjectFormat - Set the object file format
+ void setObjectFormat(ObjectFormatType Kind);
+
/// setTriple - Set all components to the new triple \p Str.
void setTriple(const Twine &Str);
diff --git a/lib/MC/MCObjectFileInfo.cpp b/lib/MC/MCObjectFileInfo.cpp
index 9a512d561f..6b21cd3dd1 100644
--- a/lib/MC/MCObjectFileInfo.cpp
+++ b/lib/MC/MCObjectFileInfo.cpp
@@ -736,10 +736,10 @@ void MCObjectFileInfo::InitMCObjectFileInfo(StringRef TT, Reloc::Model relocm,
Arch == Triple::arm || Arch == Triple::thumb ||
Arch == Triple::ppc || Arch == Triple::ppc64 ||
Arch == Triple::UnknownArch) &&
- (T.isOSDarwin() || T.getEnvironment() == Triple::MachO)) {
+ (T.isOSDarwin() || T.isOSBinFormatMachO())) {
Env = IsMachO;
InitMachOMCObjectFileInfo(T);
- } else if (T.isOSWindows() && T.getEnvironment() != Triple::ELF) {
+ } else if (T.isOSWindows() && !T.isOSBinFormatELF()) {
assert((Arch == Triple::x86 || Arch == Triple::x86_64) &&
"expected x86 or x86_64");
Env = IsCOFF;
diff --git a/lib/Support/Triple.cpp b/lib/Support/Triple.cpp
index e7bb1accd1..d09931a345 100644
--- a/lib/Support/Triple.cpp
+++ b/lib/Support/Triple.cpp
@@ -154,9 +154,7 @@ const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
case CODE16: return "code16";
case EABI: return "eabi";
case EABIHF: return "eabihf";
- case MachO: return "macho";
case Android: return "android";
- case ELF: return "elf";
}
llvm_unreachable("Invalid EnvironmentType!");
@@ -310,12 +308,36 @@ static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) {
.StartsWith("gnux32", Triple::GNUX32)
.StartsWith("code16", Triple::CODE16)
.StartsWith("gnu", Triple::GNU)
- .StartsWith("macho", Triple::MachO)
.StartsWith("android", Triple::Android)
- .StartsWith("elf", Triple::ELF)
.Default(Triple::UnknownEnvironment);
}
+static Triple::ObjectFormatType parseFormat(StringRef EnvironmentName) {
+ return StringSwitch<Triple::ObjectFormatType>(EnvironmentName)
+ .EndsWith("coff", Triple::COFF)
+ .EndsWith("elf", Triple::ELF)
+ .EndsWith("macho", Triple::MachO)
+ .Default(Triple::UnknownObjectFormat);
+}
+
+static const char *getObjectFormatTypeName(Triple::ObjectFormatType Kind) {
+ switch (Kind) {
+ case Triple::UnknownObjectFormat: return "";
+ case Triple::COFF: return "coff";
+ case Triple::ELF: return "elf";
+ case Triple::MachO: return "macho";
+ }
+ llvm_unreachable("unknown object format type");
+}
+
+static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
+ if (T.isOSDarwin())
+ return Triple::MachO;
+ else if (T.isOSWindows())
+ return Triple::COFF;
+ return Triple::ELF;
+}
+
/// \brief Construct a triple from the string representation provided.
///
/// This stores the string representation and parses the various pieces into
@@ -325,7 +347,10 @@ Triple::Triple(const Twine &Str)
Arch(parseArch(getArchName())),
Vendor(parseVendor(getVendorName())),
OS(parseOS(getOSName())),
- Environment(parseEnvironment(getEnvironmentName())) {
+ Environment(parseEnvironment(getEnvironmentName())),
+ ObjectFormat(parseFormat(getEnvironmentName())) {
+ if (ObjectFormat == Triple::UnknownObjectFormat)
+ ObjectFormat = getDefaultFormat(*this);
}
/// \brief Construct a triple from string representations of the architecture,
@@ -339,7 +364,8 @@ Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr)
Arch(parseArch(ArchStr.str())),
Vendor(parseVendor(VendorStr.str())),
OS(parseOS(OSStr.str())),
- Environment() {
+ Environment(), ObjectFormat(Triple::UnknownObjectFormat) {
+ ObjectFormat = getDefaultFormat(*this);
}
/// \brief Construct a triple from string representations of the architecture,
@@ -354,7 +380,10 @@ Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr,
Arch(parseArch(ArchStr.str())),
Vendor(parseVendor(VendorStr.str())),
OS(parseOS(OSStr.str())),
- Environment(parseEnvironment(EnvironmentStr.str())) {
+ Environment(parseEnvironment(EnvironmentStr.str())),
+ ObjectFormat(parseFormat(EnvironmentStr.str())) {
+ if (ObjectFormat == Triple::UnknownObjectFormat)
+ ObjectFormat = getDefaultFormat(*this);
}
std::string Triple::normalize(StringRef Str) {
@@ -379,6 +408,7 @@ std::string Triple::normalize(StringRef Str) {
EnvironmentType Environment = UnknownEnvironment;
if (Components.size() > 3)
Environment = parseEnvironment(Components[3]);
+ ObjectFormatType ObjectFormat = UnknownObjectFormat;
// Note which components are already in their final position. These will not
// be moved.
@@ -420,6 +450,10 @@ std::string Triple::normalize(StringRef Str) {
case 3:
Environment = parseEnvironment(Comp);
Valid = Environment != UnknownEnvironment;
+ if (!Valid) {
+ ObjectFormat = parseFormat(Comp);
+ Valid = ObjectFormat != UnknownObjectFormat;
+ }
break;
}
if (!Valid)
@@ -641,6 +675,10 @@ void Triple::setEnvironment(EnvironmentType Kind) {
setEnvironmentName(getEnvironmentTypeName(Kind));
}
+void Triple::setObjectFormat(ObjectFormatType Kind) {
+ setEnvironmentName(getObjectFormatTypeName(Kind));
+}
+
void Triple::setArchName(StringRef Str) {
// Work around a miscompilation bug for Twines in gcc 4.0.3.
SmallString<64> Triple;
diff --git a/lib/Target/ARM/ARMSubtarget.cpp b/lib/Target/ARM/ARMSubtarget.cpp
index 8c5847777e..d510e7ebf1 100644
--- a/lib/Target/ARM/ARMSubtarget.cpp
+++ b/lib/Target/ARM/ARMSubtarget.cpp
@@ -196,11 +196,12 @@ void ARMSubtarget::resetSubtargetFeatures(StringRef CPU, StringRef FS) {
case Triple::EABIHF:
case Triple::GNUEABI:
case Triple::GNUEABIHF:
- case Triple::MachO:
TargetABI = ARM_ABI_AAPCS;
break;
default:
- if (isTargetIOS() && isMClass())
+ if ((isTargetIOS() && isMClass()) ||
+ (TargetTriple.isOSBinFormatMachO() &&
+ TargetTriple.getOS() == Triple::UnknownOS))
TargetABI = ARM_ABI_AAPCS;
else
TargetABI = ARM_ABI_APCS;
diff --git a/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
index a80be99bad..5311e42929 100644
--- a/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
+++ b/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
@@ -801,7 +801,7 @@ MCAsmBackend *llvm::createX86_32AsmBackend(const Target &T,
TheTriple.isMacOSX() &&
!TheTriple.isMacOSXVersionLT(10, 7));
- if (TheTriple.isOSWindows() && TheTriple.getEnvironment() != Triple::ELF)
+ if (TheTriple.isOSWindows() && !TheTriple.isOSBinFormatELF())
return new WindowsX86AsmBackend(T, false, CPU);
uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
@@ -824,7 +824,7 @@ MCAsmBackend *llvm::createX86_64AsmBackend(const Target &T,
!TheTriple.isMacOSXVersionLT(10, 7), CS);
}
- if (TheTriple.isOSWindows() && TheTriple.getEnvironment() != Triple::ELF)
+ if (TheTriple.isOSWindows() && !TheTriple.isOSBinFormatELF())
return new WindowsX86AsmBackend(T, true, CPU);
uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
diff --git a/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp b/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
index 81ac4ad47e..8deba94c80 100644
--- a/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
+++ b/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
@@ -276,7 +276,7 @@ static MCAsmInfo *createX86MCAsmInfo(const MCRegisterInfo &MRI, StringRef TT) {
MAI = new X86_64MCAsmInfoDarwin(TheTriple);
else
MAI = new X86MCAsmInfoDarwin(TheTriple);
- } else if (TheTriple.getEnvironment() == Triple::ELF) {
+ } else if (TheTriple.isOSBinFormatELF()) {
// Force the use of an ELF container.
MAI = new X86ELFMCAsmInfo(TheTriple);
} else if (TheTriple.getOS() == Triple::Win32) {
@@ -370,7 +370,7 @@ static MCStreamer *createMCStreamer(const Target &T, StringRef TT,
if (TheTriple.isOSBinFormatMachO())
return createMachOStreamer(Ctx, MAB, _OS, _Emitter, RelaxAll);
- if (TheTriple.isOSWindows() && TheTriple.getEnvironment() != Triple::ELF)
+ if (TheTriple.isOSWindows() && !TheTriple.isOSBinFormatELF())
return createWinCOFFStreamer(Ctx, MAB, *_Emitter, _OS, RelaxAll);
return createELFStreamer(Ctx, MAB, _OS, _Emitter, RelaxAll, NoExecStack);
diff --git a/tools/llvm-jitlistener/llvm-jitlistener.cpp b/tools/llvm-jitlistener/llvm-jitlistener.cpp
index a9bbc702a9..c159aa506d 100644
--- a/tools/llvm-jitlistener/llvm-jitlistener.cpp
+++ b/tools/llvm-jitlistener/llvm-jitlistener.cpp
@@ -138,8 +138,8 @@ protected:
if (Tuple.getTriple().empty())
Tuple.setTriple(sys::getProcessTriple());
- if (Tuple.isOSWindows() && Triple::ELF != Tuple.getEnvironment()) {
- Tuple.setEnvironment(Triple::ELF);
+ if (Tuple.isOSWindows() && !Tuple.isOSBinFormatELF()) {
+ Tuple.setObjectFormat(Triple::ELF);
TheModule->setTargetTriple(Tuple.getTriple());
}
diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp
index 7a3d0e29d9..d93e477b5c 100644
--- a/tools/llvm-objdump/llvm-objdump.cpp
+++ b/tools/llvm-objdump/llvm-objdump.cpp
@@ -166,7 +166,7 @@ static const Target *getTarget(const ObjectFile *Obj = NULL) {
// TheTriple defaults to ELF, and COFF doesn't have an environment:
// the best we can do here is indicate that it is mach-o.
if (Obj->isMachO())
- TheTriple.setEnvironment(Triple::MachO);
+ TheTriple.setObjectFormat(Triple::MachO);
}
} else
TheTriple.setTriple(Triple::normalize(TripleName));
diff --git a/unittests/ADT/TripleTest.cpp b/unittests/ADT/TripleTest.cpp
index a32a231298..efd09157a4 100644
--- a/unittests/ADT/TripleTest.cpp
+++ b/unittests/ADT/TripleTest.cpp
@@ -201,7 +201,7 @@ TEST(TripleTest, Normalization) {
EXPECT_EQ(E, Triple::normalize(Join(C[2], C[0], C[1])));
EXPECT_EQ(E, Triple::normalize(Join(C[2], C[1], C[0])));
- for (int Env = 1+Triple::UnknownEnvironment; Env <= Triple::MachO;
+ for (int Env = 1 + Triple::UnknownEnvironment; Env <= Triple::Android;
++Env) {
C[3] = Triple::getEnvironmentTypeName(Triple::EnvironmentType(Env));
@@ -497,4 +497,22 @@ TEST(TripleTest, getOSVersion) {
EXPECT_EQ((unsigned)0, Micro);
}
+TEST(TripleTest, FileFormat) {
+ EXPECT_EQ(Triple::ELF, Triple("i686-unknown-linux-gnu").getObjectFormat());
+ EXPECT_EQ(Triple::ELF, Triple("i686-unknown-freebsd").getObjectFormat());
+ EXPECT_EQ(Triple::ELF, Triple("i686-unknown-netbsd").getObjectFormat());
+ EXPECT_EQ(Triple::ELF, Triple("i686--win32-elf").getObjectFormat());
+ EXPECT_EQ(Triple::ELF, Triple("i686---elf").getObjectFormat());
+
+ EXPECT_EQ(Triple::MachO, Triple("i686-apple-macosx").getObjectFormat());
+ EXPECT_EQ(Triple::MachO, Triple("i686-apple-ios").getObjectFormat());
+ EXPECT_EQ(Triple::MachO, Triple("i686---macho").getObjectFormat());
+
+ EXPECT_EQ(Triple::COFF, Triple("i686--win32").getObjectFormat());
+
+ Triple T = Triple("");
+ T.setObjectFormat(Triple::ELF);
+ EXPECT_EQ(Triple::ELF, T.getObjectFormat());
+}
+
}