aboutsummaryrefslogtreecommitdiff
path: root/lib/Support/Triple.cpp
diff options
context:
space:
mode:
authorRenato Golin <renato.golin@arm.com>2011-01-21 18:25:47 +0000
committerRenato Golin <renato.golin@arm.com>2011-01-21 18:25:47 +0000
commit859f8183639346378ed29d1e04a4b070ebc7e97f (patch)
treec52e2cb8579093cc8e76670765e8b3f07d5e52fa /lib/Support/Triple.cpp
parent596937914548c181f2504aad3b709189e87a561b (diff)
Clang was not parsing target triples involving EABI and was generating wrong IR (wrong PCS) and passing the wrong information down llc via the target-triple printed in IR. I've fixed this by adding the parsing of EABI into LLVM's Triple class and using it to choose the correct PCS in Clang's Tools. A Clang patch is on its way to use this infrastructure.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123990 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Support/Triple.cpp')
-rw-r--r--lib/Support/Triple.cpp36
1 files changed, 33 insertions, 3 deletions
diff --git a/lib/Support/Triple.cpp b/lib/Support/Triple.cpp
index c7ad7b7611..c9da964ce1 100644
--- a/lib/Support/Triple.cpp
+++ b/lib/Support/Triple.cpp
@@ -84,6 +84,7 @@ const char *Triple::getVendorTypeName(VendorType Kind) {
case Apple: return "apple";
case PC: return "pc";
+ case NoVendor: return "none";
}
return "<invalid>";
@@ -109,6 +110,7 @@ const char *Triple::getOSTypeName(OSType Kind) {
case Win32: return "win32";
case Haiku: return "haiku";
case Minix: return "minix";
+ case NoOS: return "none";
}
return "<invalid>";
@@ -117,6 +119,9 @@ const char *Triple::getOSTypeName(OSType Kind) {
const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
switch (Kind) {
case UnknownEnvironment: return "unknown";
+ case GNU: return "gnu";
+ case GNUEABI: return "gnueabi";
+ case EABI: return "eabi";
}
return "<invalid>";
@@ -293,6 +298,8 @@ Triple::VendorType Triple::ParseVendor(StringRef VendorName) {
return Apple;
else if (VendorName == "pc")
return PC;
+ else if (VendorName == "none")
+ return NoVendor;
else
return UnknownVendor;
}
@@ -330,12 +337,21 @@ Triple::OSType Triple::ParseOS(StringRef OSName) {
return Haiku;
else if (OSName.startswith("minix"))
return Minix;
+ else if (OSName.startswith("eabi"))
+ return NoOS;
else
return UnknownOS;
}
Triple::EnvironmentType Triple::ParseEnvironment(StringRef EnvironmentName) {
- return UnknownEnvironment;
+ if (EnvironmentName.startswith("eabi"))
+ return EABI;
+ else if (EnvironmentName.startswith("gnueabi"))
+ return GNUEABI;
+ else if (EnvironmentName.startswith("gnu"))
+ return GNU;
+ else
+ return UnknownEnvironment;
}
void Triple::Parse() const {
@@ -344,7 +360,12 @@ void Triple::Parse() const {
Arch = ParseArch(getArchName());
Vendor = ParseVendor(getVendorName());
OS = ParseOS(getOSName());
- Environment = ParseEnvironment(getEnvironmentName());
+ if (OS == NoOS) {
+ // Some targets don't have an OS (embedded systems)
+ Environment = ParseEnvironment(getOSName());
+ } else {
+ Environment = ParseEnvironment(getEnvironmentName());
+ }
assert(isInitialized() && "Failed to initialize!");
}
@@ -411,7 +432,13 @@ std::string Triple::normalize(StringRef Str) {
break;
case 2:
OS = ParseOS(Comp);
- Valid = OS != UnknownOS;
+ // Some targets don't have an OS (embedded systems)
+ if (OS == NoOS) {
+ Environment = ParseEnvironment(Comp);
+ Valid = Environment != UnknownEnvironment;
+ } else {
+ Valid = OS != UnknownOS;
+ }
break;
case 3:
Environment = ParseEnvironment(Comp);
@@ -450,6 +477,9 @@ std::string Triple::normalize(StringRef Str) {
for (unsigned i = Idx; i < Components.size(); ++i) {
// Skip over any fixed components.
while (i < array_lengthof(Found) && Found[i]) ++i;
+ // Fix problem when Components vector is not big enough
+ if (i >= Components.size())
+ Components.push_back(StringRef(""));
// Place the component at the new position, getting the component
// that was at this position - it will be moved right.
std::swap(CurrentComponent, Components[i]);