CODE16,
EABI,
EABIHF,
- MachO,
Android,
- ELF
+ };
+ enum ObjectFormatType {
+ UnknownObjectFormat,
+
+ COFF,
+ ELF,
+ MachO,
};
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);
/// 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.
///
/// \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;
}
/// @}
/// 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);
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;
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!");
.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
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,
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,
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) {
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.
case 3:
Environment = parseEnvironment(Comp);
Valid = Environment != UnknownEnvironment;
+ if (!Valid) {
+ ObjectFormat = parseFormat(Comp);
+ Valid = ObjectFormat != UnknownObjectFormat;
+ }
break;
}
if (!Valid)
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;
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;
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());
!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());
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) {
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);
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());
}
// 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));
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));
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());
+}
+
}