Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions llvm/include/llvm/TargetParser/Triple.h
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,27 @@ class Triple {

const std::string &str() const { return Data; }

/// Return the triple string but only keep the first \p N components.
///
/// The returned string will preserve the first \p N components exactly the
/// same as the original (including the leading "-" and the value, empty or
/// not).
///
/// E.g. Triple("arm64-apple-ios").str(5) == "arm64-apple-ios"
/// E.g. Triple("arm64-apple-ios--").str(5) == "arm64-apple-ios--"
/// E.g. Triple("arm64-apple-ios--").str(4) == "arm64-apple-ios-"
/// E.g. Triple("arm64-apple-ios--").str(3) == "arm64-apple-ios"
/// E.g. Triple("arm64-apple-ios--").str(2) == "arm64-apple"
/// E.g. Triple("arm64-apple-ios--").str(1) == "arm64"
/// E.g. Triple("arm64-apple-ios--").str(0) == ""
///
/// This method does not normalize any triple strings. Clients that need to
/// handle the non-canonical triples that users often specify should use the
/// normalize method.
///
/// \returns the (shorterned) triple string.
StringRef str(size_t N) const;

const std::string &getTriple() const { return Data; }

/// Whether the triple is empty / default constructed.
Expand Down
24 changes: 24 additions & 0 deletions llvm/lib/TargetParser/Triple.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2107,6 +2107,30 @@ std::string Triple::merge(const Triple &Other) const {
return Other.str();
}

StringRef Triple::str(size_t N) const {
// If empty, return empty
if (N == 0 || Data == "")
return "";

// If keeping all components, return a full clone
if (N >= 5)
return Data;

// Find the N-th separator (which is after the N'th component)
size_t p = StringRef::npos;
for (uint32_t i = 0; i < N; ++i) {
p = Data.find('-', p + 1);
if (p == StringRef::npos)
break;
}

// Create a triple
if (p == StringRef::npos)
return Data;
else
return StringRef(Data).substr(0, p);
}

bool Triple::isMacOSXVersionLT(unsigned Major, unsigned Minor,
unsigned Micro) const {
assert(isMacOSX() && "Not an OS X triple!");
Expand Down
93 changes: 93 additions & 0 deletions llvm/unittests/TargetParser/TripleTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2926,4 +2926,97 @@ TEST(TripleTest, isCompatibleWith) {
EXPECT_TRUE(DoTest(C.B, C.A, C.Result));
}
}

TEST(TripleTest, StrFirstN) {
// Empty triple
{
llvm::Triple triple;
ASSERT_EQ(triple.str(), "");
ASSERT_EQ(triple.str(5), "");
}

// Normal triple with 3 components
{
llvm::Triple triple("arm64-apple-ios");
ASSERT_EQ(triple.str(), "arm64-apple-ios");
ASSERT_EQ(triple.str(5), "arm64-apple-ios");
ASSERT_EQ(triple.str(4), "arm64-apple-ios");
ASSERT_EQ(triple.str(3), "arm64-apple-ios");
ASSERT_EQ(triple.str(2), "arm64-apple");
ASSERT_EQ(triple.str(1), "arm64");
ASSERT_EQ(triple.str(0), "");
}

// Normal triple with 4 components
{
llvm::Triple triple("arm64-apple-ios-simulator");
ASSERT_EQ(triple.str(), "arm64-apple-ios-simulator");
ASSERT_EQ(triple.str(5), "arm64-apple-ios-simulator");
ASSERT_EQ(triple.str(4), "arm64-apple-ios-simulator");
ASSERT_EQ(triple.str(3), "arm64-apple-ios");
ASSERT_EQ(triple.str(2), "arm64-apple");
ASSERT_EQ(triple.str(1), "arm64");
ASSERT_EQ(triple.str(0), "");
}

// Normal triple with 5 components
{
llvm::Triple triple("arm64-apple-ios-simulator-macho");
ASSERT_EQ(triple.str(), "arm64-apple-ios-simulator-macho");
ASSERT_EQ(triple.str(5), "arm64-apple-ios-simulator-macho");
ASSERT_EQ(triple.str(4), "arm64-apple-ios-simulator");
ASSERT_EQ(triple.str(3), "arm64-apple-ios");
ASSERT_EQ(triple.str(2), "arm64-apple");
ASSERT_EQ(triple.str(1), "arm64");
ASSERT_EQ(triple.str(0), "");
}

// Empty vendor and os
{
llvm::Triple triple("arm64---simulator-macho");
ASSERT_EQ(triple.str(), "arm64---simulator-macho");
ASSERT_EQ(triple.str(5), "arm64---simulator-macho");
ASSERT_EQ(triple.str(4), "arm64---simulator");
ASSERT_EQ(triple.str(3), "arm64--");
ASSERT_EQ(triple.str(2), "arm64-");
ASSERT_EQ(triple.str(1), "arm64");
ASSERT_EQ(triple.str(0), "");
}

// Empty environment
{
llvm::Triple triple("arm64-apple-ios-");
ASSERT_EQ(triple.str(), "arm64-apple-ios-");
ASSERT_EQ(triple.str(5), "arm64-apple-ios-");
ASSERT_EQ(triple.str(4), "arm64-apple-ios-");
ASSERT_EQ(triple.str(3), "arm64-apple-ios");
ASSERT_EQ(triple.str(2), "arm64-apple");
ASSERT_EQ(triple.str(1), "arm64");
ASSERT_EQ(triple.str(0), "");
}

// Empty object format
{
llvm::Triple triple("arm64-apple-ios-simulator-");
ASSERT_EQ(triple.str(), "arm64-apple-ios-simulator-");
ASSERT_EQ(triple.str(5), "arm64-apple-ios-simulator-");
ASSERT_EQ(triple.str(4), "arm64-apple-ios-simulator");
ASSERT_EQ(triple.str(3), "arm64-apple-ios");
ASSERT_EQ(triple.str(2), "arm64-apple");
ASSERT_EQ(triple.str(1), "arm64");
ASSERT_EQ(triple.str(0), "");
}

// Empty environment, but has object format
{
llvm::Triple triple("arm64----macho");
ASSERT_EQ(triple.str(), "arm64----macho");
ASSERT_EQ(triple.str(5), "arm64----macho");
ASSERT_EQ(triple.str(4), "arm64---");
ASSERT_EQ(triple.str(3), "arm64--");
ASSERT_EQ(triple.str(2), "arm64-");
ASSERT_EQ(triple.str(1), "arm64");
ASSERT_EQ(triple.str(0), "");
}
}
} // end anonymous namespace
Loading