llvm.org GIT mirror llvm / 4eb048a
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 Saleem Abdulrasool 5 years ago
9 changed file(s) with 97 addition(s) and 27 deletion(s). Raw diff Collapse all Expand all
123123 CODE16,
124124 EABI,
125125 EABIHF,
126 Android,
127 };
128 enum ObjectFormatType {
129 UnknownObjectFormat,
130
131 COFF,
132 ELF,
126133 MachO,
127 Android,
128 ELF
129134 };
130135
131136 private:
143148 /// The parsed Environment type.
144149 EnvironmentType Environment;
145150
151 /// The object format type.
152 ObjectFormatType ObjectFormat;
153
146154 public:
147155 /// @name Constructors
148156 /// @{
149157
150158 /// \brief Default constructor is the same as an empty string and leaves all
151159 /// triple fields unknown.
152 Triple() : Data(), Arch(), Vendor(), OS(), Environment() {}
160 Triple() : Data(), Arch(), Vendor(), OS(), Environment(), ObjectFormat() {}
153161
154162 explicit Triple(const Twine &Str);
155163 Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr);
187195
188196 /// getEnvironment - Get the parsed environment type of this triple.
189197 EnvironmentType getEnvironment() const { return Environment; }
198
199 /// getFormat - Get the object format for this triple.
200 ObjectFormatType getObjectFormat() const { return ObjectFormat; }
190201
191202 /// getOSVersion - Parse the version number from the OS name component of the
192203 /// triple, if present.
343354
344355 /// \brief Tests whether the OS uses the ELF binary format.
345356 bool isOSBinFormatELF() const {
346 return !isOSBinFormatMachO() && !isOSBinFormatCOFF();
357 return getObjectFormat() == Triple::ELF;
347358 }
348359
349360 /// \brief Tests whether the OS uses the COFF binary format.
350361 bool isOSBinFormatCOFF() const {
351 return getEnvironment() != Triple::ELF &&
352 getEnvironment() != Triple::MachO && isOSWindows();
362 return getObjectFormat() == Triple::COFF;
353363 }
354364
355365 /// \brief Tests whether the environment is MachO.
356366 bool isOSBinFormatMachO() const {
357 return getEnvironment() == Triple::MachO || isOSDarwin();
367 return getObjectFormat() == Triple::MachO;
358368 }
359369
360370 /// @}
376386 /// setEnvironment - Set the environment (fourth) component of the triple
377387 /// to a known type.
378388 void setEnvironment(EnvironmentType Kind);
389
390 /// setObjectFormat - Set the object file format
391 void setObjectFormat(ObjectFormatType Kind);
379392
380393 /// setTriple - Set all components to the new triple \p Str.
381394 void setTriple(const Twine &Str);
735735 Arch == Triple::arm || Arch == Triple::thumb ||
736736 Arch == Triple::ppc || Arch == Triple::ppc64 ||
737737 Arch == Triple::UnknownArch) &&
738 (T.isOSDarwin() || T.getEnvironment() == Triple::MachO)) {
738 (T.isOSDarwin() || T.isOSBinFormatMachO())) {
739739 Env = IsMachO;
740740 InitMachOMCObjectFileInfo(T);
741 } else if (T.isOSWindows() && T.getEnvironment() != Triple::ELF) {
741 } else if (T.isOSWindows() && !T.isOSBinFormatELF()) {
742742 assert((Arch == Triple::x86 || Arch == Triple::x86_64) &&
743743 "expected x86 or x86_64");
744744 Env = IsCOFF;
153153 case CODE16: return "code16";
154154 case EABI: return "eabi";
155155 case EABIHF: return "eabihf";
156 case MachO: return "macho";
157156 case Android: return "android";
158 case ELF: return "elf";
159157 }
160158
161159 llvm_unreachable("Invalid EnvironmentType!");
309307 .StartsWith("gnux32", Triple::GNUX32)
310308 .StartsWith("code16", Triple::CODE16)
311309 .StartsWith("gnu", Triple::GNU)
312 .StartsWith("macho", Triple::MachO)
313310 .StartsWith("android", Triple::Android)
314 .StartsWith("elf", Triple::ELF)
315311 .Default(Triple::UnknownEnvironment);
312 }
313
314 static Triple::ObjectFormatType parseFormat(StringRef EnvironmentName) {
315 return StringSwitch(EnvironmentName)
316 .EndsWith("coff", Triple::COFF)
317 .EndsWith("elf", Triple::ELF)
318 .EndsWith("macho", Triple::MachO)
319 .Default(Triple::UnknownObjectFormat);
320 }
321
322 static const char *getObjectFormatTypeName(Triple::ObjectFormatType Kind) {
323 switch (Kind) {
324 case Triple::UnknownObjectFormat: return "";
325 case Triple::COFF: return "coff";
326 case Triple::ELF: return "elf";
327 case Triple::MachO: return "macho";
328 }
329 llvm_unreachable("unknown object format type");
330 }
331
332 static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
333 if (T.isOSDarwin())
334 return Triple::MachO;
335 else if (T.isOSWindows())
336 return Triple::COFF;
337 return Triple::ELF;
316338 }
317339
318340 /// \brief Construct a triple from the string representation provided.
324346 Arch(parseArch(getArchName())),
325347 Vendor(parseVendor(getVendorName())),
326348 OS(parseOS(getOSName())),
327 Environment(parseEnvironment(getEnvironmentName())) {
349 Environment(parseEnvironment(getEnvironmentName())),
350 ObjectFormat(parseFormat(getEnvironmentName())) {
351 if (ObjectFormat == Triple::UnknownObjectFormat)
352 ObjectFormat = getDefaultFormat(*this);
328353 }
329354
330355 /// \brief Construct a triple from string representations of the architecture,
338363 Arch(parseArch(ArchStr.str())),
339364 Vendor(parseVendor(VendorStr.str())),
340365 OS(parseOS(OSStr.str())),
341 Environment() {
366 Environment(), ObjectFormat(Triple::UnknownObjectFormat) {
367 ObjectFormat = getDefaultFormat(*this);
342368 }
343369
344370 /// \brief Construct a triple from string representations of the architecture,
353379 Arch(parseArch(ArchStr.str())),
354380 Vendor(parseVendor(VendorStr.str())),
355381 OS(parseOS(OSStr.str())),
356 Environment(parseEnvironment(EnvironmentStr.str())) {
382 Environment(parseEnvironment(EnvironmentStr.str())),
383 ObjectFormat(parseFormat(EnvironmentStr.str())) {
384 if (ObjectFormat == Triple::UnknownObjectFormat)
385 ObjectFormat = getDefaultFormat(*this);
357386 }
358387
359388 std::string Triple::normalize(StringRef Str) {
378407 EnvironmentType Environment = UnknownEnvironment;
379408 if (Components.size() > 3)
380409 Environment = parseEnvironment(Components[3]);
410 ObjectFormatType ObjectFormat = UnknownObjectFormat;
381411
382412 // Note which components are already in their final position. These will not
383413 // be moved.
419449 case 3:
420450 Environment = parseEnvironment(Comp);
421451 Valid = Environment != UnknownEnvironment;
452 if (!Valid) {
453 ObjectFormat = parseFormat(Comp);
454 Valid = ObjectFormat != UnknownObjectFormat;
455 }
422456 break;
423457 }
424458 if (!Valid)
640674 setEnvironmentName(getEnvironmentTypeName(Kind));
641675 }
642676
677 void Triple::setObjectFormat(ObjectFormatType Kind) {
678 setEnvironmentName(getObjectFormatTypeName(Kind));
679 }
680
643681 void Triple::setArchName(StringRef Str) {
644682 // Work around a miscompilation bug for Twines in gcc 4.0.3.
645683 SmallString<64> Triple;
195195 case Triple::EABIHF:
196196 case Triple::GNUEABI:
197197 case Triple::GNUEABIHF:
198 case Triple::MachO:
199198 TargetABI = ARM_ABI_AAPCS;
200199 break;
201200 default:
202 if (isTargetIOS() && isMClass())
201 if ((isTargetIOS() && isMClass()) ||
202 (TargetTriple.isOSBinFormatMachO() &&
203 TargetTriple.getOS() == Triple::UnknownOS))
203204 TargetABI = ARM_ABI_AAPCS;
204205 else
205206 TargetABI = ARM_ABI_APCS;
800800 TheTriple.isMacOSX() &&
801801 !TheTriple.isMacOSXVersionLT(10, 7));
802802
803 if (TheTriple.isOSWindows() && TheTriple.getEnvironment() != Triple::ELF)
803 if (TheTriple.isOSWindows() && !TheTriple.isOSBinFormatELF())
804804 return new WindowsX86AsmBackend(T, false, CPU);
805805
806806 uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
823823 !TheTriple.isMacOSXVersionLT(10, 7), CS);
824824 }
825825
826 if (TheTriple.isOSWindows() && TheTriple.getEnvironment() != Triple::ELF)
826 if (TheTriple.isOSWindows() && !TheTriple.isOSBinFormatELF())
827827 return new WindowsX86AsmBackend(T, true, CPU);
828828
829829 uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
275275 MAI = new X86_64MCAsmInfoDarwin(TheTriple);
276276 else
277277 MAI = new X86MCAsmInfoDarwin(TheTriple);
278 } else if (TheTriple.getEnvironment() == Triple::ELF) {
278 } else if (TheTriple.isOSBinFormatELF()) {
279279 // Force the use of an ELF container.
280280 MAI = new X86ELFMCAsmInfo(TheTriple);
281281 } else if (TheTriple.getOS() == Triple::Win32) {
369369 if (TheTriple.isOSBinFormatMachO())
370370 return createMachOStreamer(Ctx, MAB, _OS, _Emitter, RelaxAll);
371371
372 if (TheTriple.isOSWindows() && TheTriple.getEnvironment() != Triple::ELF)
372 if (TheTriple.isOSWindows() && !TheTriple.isOSBinFormatELF())
373373 return createWinCOFFStreamer(Ctx, MAB, *_Emitter, _OS, RelaxAll);
374374
375375 return createELFStreamer(Ctx, MAB, _OS, _Emitter, RelaxAll, NoExecStack);
137137 if (Tuple.getTriple().empty())
138138 Tuple.setTriple(sys::getProcessTriple());
139139
140 if (Tuple.isOSWindows() && Triple::ELF != Tuple.getEnvironment()) {
141 Tuple.setEnvironment(Triple::ELF);
140 if (Tuple.isOSWindows() && !Tuple.isOSBinFormatELF()) {
141 Tuple.setObjectFormat(Triple::ELF);
142142 TheModule->setTargetTriple(Tuple.getTriple());
143143 }
144144
165165 // TheTriple defaults to ELF, and COFF doesn't have an environment:
166166 // the best we can do here is indicate that it is mach-o.
167167 if (Obj->isMachO())
168 TheTriple.setEnvironment(Triple::MachO);
168 TheTriple.setObjectFormat(Triple::MachO);
169169 }
170170 } else
171171 TheTriple.setTriple(Triple::normalize(TripleName));
200200 EXPECT_EQ(E, Triple::normalize(Join(C[2], C[0], C[1])));
201201 EXPECT_EQ(E, Triple::normalize(Join(C[2], C[1], C[0])));
202202
203 for (int Env = 1+Triple::UnknownEnvironment; Env <= Triple::MachO;
203 for (int Env = 1 + Triple::UnknownEnvironment; Env <= Triple::Android;
204204 ++Env) {
205205 C[3] = Triple::getEnvironmentTypeName(Triple::EnvironmentType(Env));
206206
496496 EXPECT_EQ((unsigned)0, Micro);
497497 }
498498
499 }
499 TEST(TripleTest, FileFormat) {
500 EXPECT_EQ(Triple::ELF, Triple("i686-unknown-linux-gnu").getObjectFormat());
501 EXPECT_EQ(Triple::ELF, Triple("i686-unknown-freebsd").getObjectFormat());
502 EXPECT_EQ(Triple::ELF, Triple("i686-unknown-netbsd").getObjectFormat());
503 EXPECT_EQ(Triple::ELF, Triple("i686--win32-elf").getObjectFormat());
504 EXPECT_EQ(Triple::ELF, Triple("i686---elf").getObjectFormat());
505
506 EXPECT_EQ(Triple::MachO, Triple("i686-apple-macosx").getObjectFormat());
507 EXPECT_EQ(Triple::MachO, Triple("i686-apple-ios").getObjectFormat());
508 EXPECT_EQ(Triple::MachO, Triple("i686---macho").getObjectFormat());
509
510 EXPECT_EQ(Triple::COFF, Triple("i686--win32").getObjectFormat());
511
512 Triple T = Triple("");
513 T.setObjectFormat(Triple::ELF);
514 EXPECT_EQ(Triple::ELF, T.getObjectFormat());
515 }
516
517 }