mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 02:33:06 +01:00
Avoid keeping internal string_views in Twine.
This is a follow-up to https://reviews.llvm.org/D103935 A Twine's internal layout should not depend on which version of the C++ standard is in use. Dynamically linking binaries compiled with two different layouts (eg, --std=c++14 vs --std=c++17) ends up problematic. This change avoids that issue by immediately converting a string_view to a pointer-and-length at the cost of an extra eight-bytes in Twine. Differential Revision: https://reviews.llvm.org/D106186
This commit is contained in:
parent
9d554c2dc6
commit
4a2706ecc3
@ -102,14 +102,14 @@ namespace llvm {
|
||||
/// A pointer to a StringRef instance.
|
||||
StringRefKind,
|
||||
|
||||
#if __cplusplus > 201402L
|
||||
// A pointer to a std::string_view instance.
|
||||
StdStringViewKind,
|
||||
#endif
|
||||
|
||||
/// A pointer to a SmallString instance.
|
||||
SmallStringKind,
|
||||
|
||||
/// A Pointer and Length representation. Used for std::string_view.
|
||||
/// Can't use a StringRef here because they are not trivally
|
||||
/// constructible.
|
||||
PtrAndLengthKind,
|
||||
|
||||
/// A pointer to a formatv_object_base instance.
|
||||
FormatvObjectKind,
|
||||
|
||||
@ -145,11 +145,12 @@ namespace llvm {
|
||||
{
|
||||
const Twine *twine;
|
||||
const char *cString;
|
||||
struct {
|
||||
const char *ptr;
|
||||
size_t length;
|
||||
} ptrAndLength;
|
||||
const std::string *stdString;
|
||||
const StringRef *stringRef;
|
||||
#if __cplusplus > 201402L
|
||||
const std::string_view *stdStringView;
|
||||
#endif
|
||||
const SmallVectorImpl<char> *smallString;
|
||||
const formatv_object_base *formatvObject;
|
||||
char character;
|
||||
@ -295,10 +296,14 @@ namespace llvm {
|
||||
}
|
||||
|
||||
#if __cplusplus > 201402L
|
||||
/// Construct from an std::string_view.
|
||||
/// Construct from an std::string_view by converting it to a pointer and
|
||||
/// length. 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(StdStringViewKind) {
|
||||
LHS.stdStringView = &Str;
|
||||
: LHSKind(PtrAndLengthKind) {
|
||||
LHS.ptrAndLength.ptr = Str.data();
|
||||
LHS.ptrAndLength.length = Str.length();
|
||||
assert(isValid() && "Invalid twine!");
|
||||
}
|
||||
#endif
|
||||
@ -430,11 +435,9 @@ namespace llvm {
|
||||
case EmptyKind:
|
||||
case CStringKind:
|
||||
case StdStringKind:
|
||||
#if __cplusplus > 201402L
|
||||
case StdStringViewKind:
|
||||
#endif
|
||||
case StringRefKind:
|
||||
case SmallStringKind:
|
||||
case PtrAndLengthKind:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@ -469,14 +472,12 @@ namespace llvm {
|
||||
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;
|
||||
case SmallStringKind:
|
||||
return StringRef(LHS.smallString->data(), LHS.smallString->size());
|
||||
case PtrAndLengthKind:
|
||||
return StringRef(LHS.ptrAndLength.ptr, LHS.ptrAndLength.length);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,14 +65,12 @@ void Twine::printOneChild(raw_ostream &OS, Child Ptr,
|
||||
case Twine::CStringKind:
|
||||
OS << Ptr.cString;
|
||||
break;
|
||||
case Twine::PtrAndLengthKind:
|
||||
OS << StringRef(Ptr.ptrAndLength.ptr, Ptr.ptrAndLength.length);
|
||||
break;
|
||||
case Twine::StdStringKind:
|
||||
OS << *Ptr.stdString;
|
||||
break;
|
||||
#if __cplusplus > 201402L
|
||||
case StdStringViewKind:
|
||||
OS << StringRef(*Ptr.stdStringView);
|
||||
break;
|
||||
#endif
|
||||
case Twine::StringRefKind:
|
||||
OS << *Ptr.stringRef;
|
||||
break;
|
||||
@ -124,15 +122,14 @@ void Twine::printOneChildRepr(raw_ostream &OS, Child Ptr,
|
||||
OS << "cstring:\""
|
||||
<< Ptr.cString << "\"";
|
||||
break;
|
||||
case Twine::PtrAndLengthKind:
|
||||
OS << "ptrAndLength:\""
|
||||
<< StringRef(Ptr.ptrAndLength.ptr, Ptr.ptrAndLength.length) << "\"";
|
||||
break;
|
||||
case Twine::StdStringKind:
|
||||
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 << "\"";
|
||||
|
@ -77,7 +77,7 @@ TEST(TwineTest, Concat) {
|
||||
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\")",
|
||||
EXPECT_EQ("(Twine ptrAndLength:\"hey\" cstring:\"there\")",
|
||||
repr(Twine(std::string_view("hey")).concat(Twine("there"))));
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user