mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 10:42:39 +01:00
Add llvm::Triple class for abstracting access to target triples.
- The code is silly, I'm just amusing myself. Rewrite to be efficient if you like. :) Also, if you wish to debate the proper names of the triple components I'm all ears. llvm-svn: 68252
This commit is contained in:
parent
dd9c6eb7ba
commit
588d3d1fd6
196
include/llvm/ADT/Triple.h
Normal file
196
include/llvm/ADT/Triple.h
Normal file
@ -0,0 +1,196 @@
|
||||
//===-- llvm/ADT/Triple.h - Target triple helper class ----------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_ADT_TRIPLE_H
|
||||
#define LLVM_ADT_TRIPLE_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// Triple - Helper class for working with target triples.
|
||||
///
|
||||
/// Target triples are strings in the format of:
|
||||
/// ARCHITECTURE-VENDOR-OPERATING_SYSTEM
|
||||
/// or
|
||||
/// ARCHITECTURE-VENDOR-OPERATING_SYSTEM-ENVIRONMENT
|
||||
///
|
||||
/// This class is used for clients which want to support arbitrary
|
||||
/// target triples, but also want to implement certain special
|
||||
/// behavior for particular targets. This class isolates the mapping
|
||||
/// from the components of the target triple to well known IDs.
|
||||
///
|
||||
/// See autoconf/config.guess for a glimpse into what they look like
|
||||
/// in practice.
|
||||
class Triple {
|
||||
public:
|
||||
enum ArchType {
|
||||
UnknownArch,
|
||||
|
||||
x86, // i?86
|
||||
ppc, // powerpc
|
||||
ppc64, // powerpc64
|
||||
x86_64, // amd64, x86_64
|
||||
|
||||
InvalidArch
|
||||
};
|
||||
enum VendorType {
|
||||
UnknownVendor,
|
||||
|
||||
Apple,
|
||||
PC
|
||||
};
|
||||
enum OSType {
|
||||
UnknownOS,
|
||||
|
||||
Darwin,
|
||||
FreeBSD,
|
||||
Linux
|
||||
};
|
||||
|
||||
private:
|
||||
std::string Data;
|
||||
|
||||
/// The parsed arch type (or InvalidArch if uninitialized).
|
||||
mutable ArchType Arch;
|
||||
|
||||
/// The parsed vendor type.
|
||||
mutable VendorType Vendor;
|
||||
|
||||
/// The parsed OS type.
|
||||
mutable OSType OS;
|
||||
|
||||
bool isInitialized() const { return Arch != InvalidArch; }
|
||||
void Parse() const;
|
||||
|
||||
public:
|
||||
/// @name Constructors
|
||||
/// @{
|
||||
|
||||
Triple() : Data(""), Arch(InvalidArch) {}
|
||||
explicit Triple(const char *Str) : Data(Str), Arch(InvalidArch) {}
|
||||
|
||||
/// @}
|
||||
/// @name Typed Component Access
|
||||
/// @{
|
||||
|
||||
/// getArch - Get the parsed architecture type of this triple.
|
||||
ArchType getArch() const {
|
||||
if (!isInitialized()) Parse();
|
||||
return Arch;
|
||||
}
|
||||
|
||||
/// getVendor - Get the parsed vendor type of this triple.
|
||||
VendorType getVendor() const {
|
||||
if (!isInitialized()) Parse();
|
||||
return Vendor;
|
||||
}
|
||||
|
||||
/// getOS - Get the parsed operating system type of this triple.
|
||||
OSType getOS() const {
|
||||
if (!isInitialized()) Parse();
|
||||
return OS;
|
||||
}
|
||||
|
||||
/// hasEnvironment - Does this triple have the optional environment
|
||||
/// (fourth) component?
|
||||
bool hasEnvironment() const {
|
||||
return getEnvironmentName() != "";
|
||||
}
|
||||
|
||||
/// @}
|
||||
/// @name Direct Component Access
|
||||
/// @{
|
||||
|
||||
const std::string &getTriple() const { return Data; }
|
||||
|
||||
// FIXME: Invent a lightweight string representation for these to
|
||||
// use.
|
||||
|
||||
/// getArchName - Get the architecture (first) component of the
|
||||
/// triple.
|
||||
std::string getArchName() const;
|
||||
|
||||
/// getVendorName - Get the vendor (second) component of the triple.
|
||||
std::string getVendorName() const;
|
||||
|
||||
/// getOSName - Get the operating system (third) component of the
|
||||
/// triple.
|
||||
std::string getOSName() const;
|
||||
|
||||
/// getEnvironmentName - Get the optional environment (fourth)
|
||||
/// component of the triple, or "" if empty.
|
||||
std::string getEnvironmentName() const;
|
||||
|
||||
/// getOSAndEnvironmentName - Get the operating system and optional
|
||||
/// environment components as a single string (separated by a '-'
|
||||
/// if the environment component is present).
|
||||
std::string getOSAndEnvironmentName() const;
|
||||
|
||||
/// @}
|
||||
/// @name Mutators
|
||||
/// @{
|
||||
|
||||
/// setArch - Set the architecture (first) component of the triple
|
||||
/// to a known type.
|
||||
void setArch(ArchType Kind);
|
||||
|
||||
/// setVendor - Set the vendor (second) component of the triple to a
|
||||
/// known type.
|
||||
void setVendor(VendorType Kind);
|
||||
|
||||
/// setOS - Set the operating system (third) component of the triple
|
||||
/// to a known type.
|
||||
void setOS(OSType Kind);
|
||||
|
||||
/// setTriple - Set all components to the new triple \arg Str.
|
||||
void setTriple(const std::string &Str);
|
||||
|
||||
/// setArchName - Set the architecture (first) component of the
|
||||
/// triple by name.
|
||||
void setArchName(const std::string &Str);
|
||||
|
||||
/// setVendorName - Set the vendor (second) component of the triple
|
||||
/// by name.
|
||||
void setVendorName(const std::string &Str);
|
||||
|
||||
/// setOSName - Set the operating system (third) component of the
|
||||
/// triple by name.
|
||||
void setOSName(const std::string &Str);
|
||||
|
||||
/// setEnvironmentName - Set the optional environment (fourth)
|
||||
/// component of the triple by name.
|
||||
void setEnvironmentName(const std::string &Str);
|
||||
|
||||
/// setOSAndEnvironmentName - Set the operating system and optional
|
||||
/// environment components with a single string.
|
||||
void setOSAndEnvironmentName(const std::string &Str);
|
||||
|
||||
/// @}
|
||||
/// @name Static helpers for IDs.
|
||||
/// @{
|
||||
|
||||
/// getArchTypeName - Get the canonical name for the \arg Kind
|
||||
/// architecture.
|
||||
static const char *getArchTypeName(ArchType Kind);
|
||||
|
||||
/// getVendorTypeName - Get the canonical name for the \arg Kind
|
||||
/// vendor.
|
||||
static const char *getVendorTypeName(VendorType Kind);
|
||||
|
||||
/// getOSTypeName - Get the canonical name for the \arg Kind vendor.
|
||||
static const char *getOSTypeName(OSType Kind);
|
||||
|
||||
/// @}
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
|
||||
#endif
|
183
lib/Support/Triple.cpp
Normal file
183
lib/Support/Triple.cpp
Normal file
@ -0,0 +1,183 @@
|
||||
//===--- Triple.cpp - Target triple helper class --------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include <cassert>
|
||||
using namespace llvm;
|
||||
|
||||
//
|
||||
|
||||
const char *Triple::getArchTypeName(ArchType Kind) {
|
||||
switch (Kind) {
|
||||
case InvalidArch: return "<invalid>";
|
||||
case UnknownArch: return "unknown";
|
||||
|
||||
case x86: return "i386";
|
||||
case x86_64: return "x86_64";
|
||||
case ppc: return "powerpc";
|
||||
case ppc64: return "powerpc64";
|
||||
}
|
||||
|
||||
return "<invalid>";
|
||||
}
|
||||
|
||||
const char *Triple::getVendorTypeName(VendorType Kind) {
|
||||
switch (Kind) {
|
||||
case UnknownVendor: return "unknown";
|
||||
|
||||
case Apple: return "apple";
|
||||
case PC: return "PC";
|
||||
}
|
||||
|
||||
return "<invalid>";
|
||||
}
|
||||
|
||||
const char *Triple::getOSTypeName(OSType Kind) {
|
||||
switch (Kind) {
|
||||
case UnknownOS: return "unknown";
|
||||
|
||||
case Darwin: return "darwin";
|
||||
case FreeBSD: return "freebsd";
|
||||
case Linux: return "linux";
|
||||
}
|
||||
|
||||
return "<invalid>";
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
void Triple::Parse() const {
|
||||
assert(!isInitialized() && "Invalid parse call.");
|
||||
|
||||
std::string ArchName = getArchName();
|
||||
if (ArchName.size() == 4 && ArchName[0] == 'i' &&
|
||||
ArchName[2] == '8' && ArchName[3] == '6')
|
||||
Arch = x86;
|
||||
else if (ArchName == "amd64" || ArchName == "x86_64")
|
||||
Arch = x86_64;
|
||||
else if (ArchName == "powerpc")
|
||||
Arch = ppc;
|
||||
else if (ArchName == "powerpc64")
|
||||
Arch = ppc64;
|
||||
else
|
||||
Arch = UnknownArch;
|
||||
|
||||
std::string VendorName = getVendorName();
|
||||
if (VendorName == "apple")
|
||||
Vendor = Apple;
|
||||
else if (VendorName == "pc")
|
||||
Vendor = PC;
|
||||
else
|
||||
Vendor = UnknownVendor;
|
||||
|
||||
std::string OSName = getOSName();
|
||||
if (memcmp(&OSName[0], "darwin", 6) == 0)
|
||||
OS = Darwin;
|
||||
else if (memcmp(&OSName[0], "freebsd", 7) == 0)
|
||||
OS = FreeBSD;
|
||||
else if (memcmp(&OSName[0], "linux", 5) == 0)
|
||||
OS = Linux;
|
||||
else
|
||||
OS = UnknownOS;
|
||||
|
||||
assert(isInitialized() && "Failed to initialize!");
|
||||
}
|
||||
|
||||
static std::string extract(const std::string &A,
|
||||
std::string::size_type begin,
|
||||
std::string::size_type end) {
|
||||
if (begin == std::string::npos)
|
||||
return "";
|
||||
if (end == std::string::npos)
|
||||
return A.substr(begin);
|
||||
return A.substr(begin, end - begin);
|
||||
}
|
||||
|
||||
static std::string extract1(const std::string &A,
|
||||
std::string::size_type begin,
|
||||
std::string::size_type end) {
|
||||
if (begin == std::string::npos || begin == end)
|
||||
return "";
|
||||
return extract(A, begin + 1, end);
|
||||
}
|
||||
|
||||
std::string Triple::getArchName() const {
|
||||
std::string Tmp = Data;
|
||||
return extract(Tmp, 0, Tmp.find('-'));
|
||||
}
|
||||
|
||||
std::string Triple::getVendorName() const {
|
||||
std::string Tmp = Data;
|
||||
Tmp = extract1(Tmp, Tmp.find('-'), std::string::npos);
|
||||
return extract(Tmp, 0, Tmp.find('-'));
|
||||
}
|
||||
|
||||
std::string Triple::getOSName() const {
|
||||
std::string Tmp = Data;
|
||||
Tmp = extract1(Tmp, Tmp.find('-'), std::string::npos);
|
||||
Tmp = extract1(Tmp, Tmp.find('-'), std::string::npos);
|
||||
return extract(Tmp, 0, Tmp.find('-'));
|
||||
}
|
||||
|
||||
std::string Triple::getEnvironmentName() const {
|
||||
std::string Tmp = Data;
|
||||
Tmp = extract1(Tmp, Tmp.find('-'), std::string::npos);
|
||||
Tmp = extract1(Tmp, Tmp.find('-'), std::string::npos);
|
||||
Tmp = extract1(Tmp, Tmp.find('-'), std::string::npos);
|
||||
return extract(Tmp, 0, std::string::npos);
|
||||
}
|
||||
|
||||
std::string Triple::getOSAndEnvironmentName() const {
|
||||
std::string Tmp = Data;
|
||||
Tmp = extract1(Tmp, Tmp.find('-'), std::string::npos);
|
||||
Tmp = extract1(Tmp, Tmp.find('-'), std::string::npos);
|
||||
return extract(Tmp, 0, std::string::npos);
|
||||
}
|
||||
|
||||
void Triple::setTriple(const std::string &Str) {
|
||||
Data = Str;
|
||||
Arch = InvalidArch;
|
||||
}
|
||||
|
||||
void Triple::setArch(ArchType Kind) {
|
||||
setArchName(getArchTypeName(Kind));
|
||||
}
|
||||
|
||||
void Triple::setVendor(VendorType Kind) {
|
||||
setVendorName(getVendorTypeName(Kind));
|
||||
}
|
||||
|
||||
void Triple::setOS(OSType Kind) {
|
||||
setOSName(getOSTypeName(Kind));
|
||||
}
|
||||
|
||||
void Triple::setArchName(const std::string &Str) {
|
||||
setTriple(Str + "-" + getVendorName() + "-" + getOSAndEnvironmentName());
|
||||
}
|
||||
|
||||
void Triple::setVendorName(const std::string &Str) {
|
||||
setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
|
||||
}
|
||||
|
||||
void Triple::setOSName(const std::string &Str) {
|
||||
if (hasEnvironment())
|
||||
setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
|
||||
"-" + getEnvironmentName());
|
||||
else
|
||||
setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
|
||||
}
|
||||
|
||||
void Triple::setEnvironmentName(const std::string &Str) {
|
||||
setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
|
||||
"-" + Str);
|
||||
}
|
||||
|
||||
void Triple::setOSAndEnvironmentName(const std::string &Str) {
|
||||
setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
|
||||
}
|
137
unittests/ADT/TripleTest.cpp
Normal file
137
unittests/ADT/TripleTest.cpp
Normal file
@ -0,0 +1,137 @@
|
||||
//===----------- Triple.cpp - Triple unit tests ---------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
|
||||
TEST(TripleTest, BasicParsing) {
|
||||
Triple T;
|
||||
|
||||
T = Triple("");
|
||||
EXPECT_EQ(T.getArchName(), "");
|
||||
EXPECT_EQ(T.getVendorName(), "");
|
||||
EXPECT_EQ(T.getOSName(), "");
|
||||
EXPECT_EQ(T.getEnvironmentName(), "");
|
||||
|
||||
T = Triple("-");
|
||||
EXPECT_EQ(T.getArchName(), "");
|
||||
EXPECT_EQ(T.getVendorName(), "");
|
||||
EXPECT_EQ(T.getOSName(), "");
|
||||
EXPECT_EQ(T.getEnvironmentName(), "");
|
||||
|
||||
T = Triple("--");
|
||||
EXPECT_EQ(T.getArchName(), "");
|
||||
EXPECT_EQ(T.getVendorName(), "");
|
||||
EXPECT_EQ(T.getOSName(), "");
|
||||
EXPECT_EQ(T.getEnvironmentName(), "");
|
||||
|
||||
T = Triple("---");
|
||||
EXPECT_EQ(T.getArchName(), "");
|
||||
EXPECT_EQ(T.getVendorName(), "");
|
||||
EXPECT_EQ(T.getOSName(), "");
|
||||
EXPECT_EQ(T.getEnvironmentName(), "");
|
||||
|
||||
T = Triple("----");
|
||||
EXPECT_EQ(T.getArchName(), "");
|
||||
EXPECT_EQ(T.getVendorName(), "");
|
||||
EXPECT_EQ(T.getOSName(), "");
|
||||
EXPECT_EQ(T.getEnvironmentName(), "-");
|
||||
|
||||
T = Triple("a");
|
||||
EXPECT_EQ(T.getArchName(), "a");
|
||||
EXPECT_EQ(T.getVendorName(), "");
|
||||
EXPECT_EQ(T.getOSName(), "");
|
||||
EXPECT_EQ(T.getEnvironmentName(), "");
|
||||
|
||||
T = Triple("a-b");
|
||||
EXPECT_EQ(T.getArchName(), "a");
|
||||
EXPECT_EQ(T.getVendorName(), "b");
|
||||
EXPECT_EQ(T.getOSName(), "");
|
||||
EXPECT_EQ(T.getEnvironmentName(), "");
|
||||
|
||||
T = Triple("a-b-c");
|
||||
EXPECT_EQ(T.getArchName(), "a");
|
||||
EXPECT_EQ(T.getVendorName(), "b");
|
||||
EXPECT_EQ(T.getOSName(), "c");
|
||||
EXPECT_EQ(T.getEnvironmentName(), "");
|
||||
|
||||
T = Triple("a-b-c-d");
|
||||
EXPECT_EQ(T.getArchName(), "a");
|
||||
EXPECT_EQ(T.getVendorName(), "b");
|
||||
EXPECT_EQ(T.getOSName(), "c");
|
||||
EXPECT_EQ(T.getEnvironmentName(), "d");
|
||||
}
|
||||
|
||||
TEST(TripleTest, ParsedIDs) {
|
||||
Triple T;
|
||||
|
||||
T = Triple("i386-apple-darwin");
|
||||
EXPECT_EQ(T.getArch(), Triple::x86);
|
||||
EXPECT_EQ(T.getVendor(), Triple::Apple);
|
||||
EXPECT_EQ(T.getOS(), Triple::Darwin);
|
||||
|
||||
T = Triple("x86_64-pc-linux-gnu");
|
||||
EXPECT_EQ(T.getArch(), Triple::x86_64);
|
||||
EXPECT_EQ(T.getVendor(), Triple::PC);
|
||||
EXPECT_EQ(T.getOS(), Triple::Linux);
|
||||
|
||||
T = Triple("powerpc-dunno-notsure");
|
||||
EXPECT_EQ(T.getArch(), Triple::ppc);
|
||||
EXPECT_EQ(T.getVendor(), Triple::UnknownVendor);
|
||||
EXPECT_EQ(T.getOS(), Triple::UnknownOS);
|
||||
|
||||
T = Triple("huh");
|
||||
EXPECT_EQ(T.getArch(), Triple::UnknownArch);
|
||||
}
|
||||
|
||||
TEST(TripleTest, MutateName) {
|
||||
Triple T;
|
||||
EXPECT_EQ(T.getArch(), Triple::UnknownArch);
|
||||
EXPECT_EQ(T.getVendor(), Triple::UnknownVendor);
|
||||
EXPECT_EQ(T.getOS(), Triple::UnknownOS);
|
||||
|
||||
T.setArchName("i386");
|
||||
EXPECT_EQ(T.getArch(), Triple::x86);
|
||||
EXPECT_EQ(T.getTriple(), "i386--");
|
||||
|
||||
T.setVendorName("pc");
|
||||
EXPECT_EQ(T.getArch(), Triple::x86);
|
||||
EXPECT_EQ(T.getVendor(), Triple::PC);
|
||||
EXPECT_EQ(T.getTriple(), "i386-pc-");
|
||||
|
||||
T.setOSName("linux");
|
||||
EXPECT_EQ(T.getArch(), Triple::x86);
|
||||
EXPECT_EQ(T.getVendor(), Triple::PC);
|
||||
EXPECT_EQ(T.getOS(), Triple::Linux);
|
||||
EXPECT_EQ(T.getTriple(), "i386-pc-linux");
|
||||
|
||||
T.setEnvironmentName("gnu");
|
||||
EXPECT_EQ(T.getArch(), Triple::x86);
|
||||
EXPECT_EQ(T.getVendor(), Triple::PC);
|
||||
EXPECT_EQ(T.getOS(), Triple::Linux);
|
||||
EXPECT_EQ(T.getTriple(), "i386-pc-linux-gnu");
|
||||
|
||||
T.setOSName("freebsd");
|
||||
EXPECT_EQ(T.getArch(), Triple::x86);
|
||||
EXPECT_EQ(T.getVendor(), Triple::PC);
|
||||
EXPECT_EQ(T.getOS(), Triple::FreeBSD);
|
||||
EXPECT_EQ(T.getTriple(), "i386-pc-freebsd-gnu");
|
||||
|
||||
T.setOSAndEnvironmentName("darwin");
|
||||
EXPECT_EQ(T.getArch(), Triple::x86);
|
||||
EXPECT_EQ(T.getVendor(), Triple::PC);
|
||||
EXPECT_EQ(T.getOS(), Triple::Darwin);
|
||||
EXPECT_EQ(T.getTriple(), "i386-pc-darwin");
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user