Support: split object format out of environment
authorSaleem Abdulrasool <compnerd@compnerd.org>
Thu, 6 Mar 2014 20:47:11 +0000 (20:47 +0000)
committerSaleem Abdulrasool <compnerd@compnerd.org>
Thu, 6 Mar 2014 20:47:11 +0000 (20:47 +0000)
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

include/llvm/ADT/Triple.h
lib/MC/MCObjectFileInfo.cpp
lib/Support/Triple.cpp
lib/Target/ARM/ARMSubtarget.cpp
lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
tools/llvm-jitlistener/llvm-jitlistener.cpp
tools/llvm-objdump/llvm-objdump.cpp
unittests/ADT/TripleTest.cpp

index 9238f5af7a149370db22ad16c24f669256cc2526..0eb0420f564f1c8ac0fcd9c8789489c4548d1320 100644 (file)
@@ -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);
 
index 9a512d561fe2e65ef8d007109c3a3137069029d6..6b21cd3dd1c40ff59e6e51b54e6028823edac3db 100644 (file)
@@ -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;
index e7bb1accd102dda3fed3a761278fb190024d4b2a..d09931a34564256a9c85dcb4516a8360d65b6a41 100644 (file)
@@ -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;
index 8c5847777e85bc4b0b99561c463e8e9e59d691fc..d510e7ebf100106ab7ff68bbecc899a298c246c1 100644 (file)
@@ -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;
index a80be99bad98455b42a88b85575bec44f6fe1e74..5311e429294be74570a0270a26f0a343012716a5 100644 (file)
@@ -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());
index 81ac4ad47e4d882a9f507b07ae4e9d1ce1e4b421..8deba94c80e89801f18f54117ff93433ccf97886 100644 (file)
@@ -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);
index a9bbc702a90406f783fcf4d7dbd48ad305f394b6..c159aa506d6a16c8cf79675fe69dc4bb27d51cdb 100644 (file)
@@ -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());
     }
 
index 7a3d0e29d9649dc6cf9ce01d5c2751b8805048da..d93e477b5c168d1af60ba316fac9d4f24ebe5b37 100644 (file)
@@ -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));
index a32a23129863ef89235869b440dcc460bb7406dd..efd09157a47691742d4303d5d7d012973bde57a0 100644 (file)
@@ -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());
+}
+
 }