diff --git a/llvm/include/llvm/ADT/Twine.h b/llvm/include/llvm/ADT/Twine.h --- a/llvm/include/llvm/ADT/Twine.h +++ b/llvm/include/llvm/ADT/Twine.h @@ -99,14 +99,9 @@ /// A pointer to an std::string instance. StdStringKind, - /// A pointer to a StringRef instance. + /// A StringRef instance. StringRefKind, -#if __cplusplus > 201402L - // A pointer to a std::string_view instance. - StdStringViewKind, -#endif - /// A pointer to a SmallString instance. SmallStringKind, @@ -146,10 +141,7 @@ const Twine *twine; const char *cString; const std::string *stdString; - const StringRef *stringRef; -#if __cplusplus > 201402L - const std::string_view *stdStringView; -#endif + StringRef stringRef; const SmallVectorImpl *smallString; const formatv_object_base *formatvObject; char character; @@ -160,6 +152,7 @@ const unsigned long long *decULL; const long long *decLL; const uint64_t *uHex; + Child() : stringRef(){}; }; /// LHS - The prefix in the concatenation, which may be uninitialized for @@ -295,17 +288,19 @@ } #if __cplusplus > 201402L - /// Construct from an std::string_view. - /*implicit*/ Twine(const std::string_view &Str) - : LHSKind(StdStringViewKind) { - LHS.stdStringView = &Str; + /// Construct from an std::string_view by converting it to a StringRef. + /// This handles string_views on a pure API basis, and avoids storing one + /// (or a pointer to one) inside a Twine, which avoids problems when mixing + /// code compiled under various C++ standards. + /*implicit*/ Twine(const std::string_view &Str) : LHSKind(StringRefKind) { + LHS.stringRef = Str; assert(isValid() && "Invalid twine!"); } #endif /// Construct from a StringRef. /*implicit*/ Twine(const StringRef &Str) : LHSKind(StringRefKind) { - LHS.stringRef = &Str; + LHS.stringRef = Str; assert(isValid() && "Invalid twine!"); } @@ -377,14 +372,14 @@ /*implicit*/ Twine(const char *LHS, const StringRef &RHS) : LHSKind(CStringKind), RHSKind(StringRefKind) { this->LHS.cString = LHS; - this->RHS.stringRef = &RHS; + this->RHS.stringRef = RHS; assert(isValid() && "Invalid twine!"); } /// Construct as the concatenation of a StringRef and a C string. /*implicit*/ Twine(const StringRef &LHS, const char *RHS) : LHSKind(StringRefKind), RHSKind(CStringKind) { - this->LHS.stringRef = &LHS; + this->LHS.stringRef = LHS; this->RHS.cString = RHS; assert(isValid() && "Invalid twine!"); } @@ -430,9 +425,6 @@ case EmptyKind: case CStringKind: case StdStringKind: -#if __cplusplus > 201402L - case StdStringViewKind: -#endif case StringRefKind: case SmallStringKind: return true; @@ -469,12 +461,8 @@ return StringRef(LHS.cString); case StdStringKind: return StringRef(*LHS.stdString); -#if __cplusplus > 201402L - case StdStringViewKind: - return StringRef(*LHS.stdStringView); -#endif case StringRefKind: - return *LHS.stringRef; + return LHS.stringRef; case SmallStringKind: return StringRef(LHS.smallString->data(), LHS.smallString->size()); } diff --git a/llvm/lib/Support/Twine.cpp b/llvm/lib/Support/Twine.cpp --- a/llvm/lib/Support/Twine.cpp +++ b/llvm/lib/Support/Twine.cpp @@ -68,13 +68,8 @@ case Twine::StdStringKind: OS << *Ptr.stdString; break; -#if __cplusplus > 201402L - case StdStringViewKind: - OS << StringRef(*Ptr.stdStringView); - break; -#endif case Twine::StringRefKind: - OS << *Ptr.stringRef; + OS << Ptr.stringRef; break; case Twine::SmallStringKind: OS << *Ptr.smallString; @@ -128,11 +123,6 @@ OS << "std::string:\"" << Ptr.stdString << "\""; break; -#if __cplusplus > 201402L - case Twine::StdStringViewKind: - OS << "std::string_view:\"" << StringRef(*Ptr.stdStringView) << "\""; - break; -#endif case Twine::StringRefKind: OS << "stringref:\"" << Ptr.stringRef << "\""; diff --git a/llvm/unittests/ADT/TwineTest.cpp b/llvm/unittests/ADT/TwineTest.cpp --- a/llvm/unittests/ADT/TwineTest.cpp +++ b/llvm/unittests/ADT/TwineTest.cpp @@ -77,7 +77,9 @@ EXPECT_EQ("(Twine smallstring:\"hey\" cstring:\"there\")", repr(Twine(SmallString<7>("hey")).concat(Twine("there")))); #if __cplusplus > 201402L - EXPECT_EQ("(Twine std::string_view:\"hey\" cstring:\"there\")", + // string_views are immediately converted to stringrefs to avoid + // C++ standard dependencies. + EXPECT_EQ("(Twine stringref:\"hey\" cstring:\"there\")", repr(Twine(std::string_view("hey")).concat(Twine("there")))); #endif