[llvm] 188586a - [ADT] clang-format Twine.{cpp,h} (NFC)
Kazu Hirata via llvm-commits
llvm-commits at lists.llvm.org
Sat Sep 6 00:49:48 PDT 2025
Author: Kazu Hirata
Date: 2025-09-06T00:49:41-07:00
New Revision: 188586a246ad1f6fe3ad021a12a952b50f7036ba
URL: https://github.com/llvm/llvm-project/commit/188586a246ad1f6fe3ad021a12a952b50f7036ba
DIFF: https://github.com/llvm/llvm-project/commit/188586a246ad1f6fe3ad021a12a952b50f7036ba.diff
LOG: [ADT] clang-format Twine.{cpp,h} (NFC)
I'm planning to modify these files.
Added:
Modified:
llvm/include/llvm/ADT/Twine.h
llvm/lib/Support/Twine.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/ADT/Twine.h b/llvm/include/llvm/ADT/Twine.h
index 4501f928834e2..4ed4898df5459 100644
--- a/llvm/include/llvm/ADT/Twine.h
+++ b/llvm/include/llvm/ADT/Twine.h
@@ -20,566 +20,540 @@
namespace llvm {
- class formatv_object_base;
- class raw_ostream;
+class formatv_object_base;
+class raw_ostream;
+
+/// Twine - A lightweight data structure for efficiently representing the
+/// concatenation of temporary values as strings.
+///
+/// A Twine is a kind of rope, it represents a concatenated string using a
+/// binary-tree, where the string is the preorder of the nodes. Since the
+/// Twine can be efficiently rendered into a buffer when its result is used,
+/// it avoids the cost of generating temporary values for intermediate string
+/// results -- particularly in cases when the Twine result is never
+/// required. By explicitly tracking the type of leaf nodes, we can also avoid
+/// the creation of temporary strings for conversions operations (such as
+/// appending an integer to a string).
+///
+/// A Twine is not intended for use directly and should not be stored, its
+/// implementation relies on the ability to store pointers to temporary stack
+/// objects which may be deallocated at the end of a statement. Twines should
+/// only be used as const references in arguments, when an API wishes
+/// to accept possibly-concatenated strings.
+///
+/// Twines support a special 'null' value, which always concatenates to form
+/// itself, and renders as an empty string. This can be returned from APIs to
+/// effectively nullify any concatenations performed on the result.
+///
+/// \b Implementation
+///
+/// Given the nature of a Twine, it is not possible for the Twine's
+/// concatenation method to construct interior nodes; the result must be
+/// represented inside the returned value. For this reason a Twine object
+/// actually holds two values, the left- and right-hand sides of a
+/// concatenation. We also have nullary Twine objects, which are effectively
+/// sentinel values that represent empty strings.
+///
+/// Thus, a Twine can effectively have zero, one, or two children. The \see
+/// isNullary(), \see isUnary(), and \see isBinary() predicates exist for
+/// testing the number of children.
+///
+/// We maintain a number of invariants on Twine objects (FIXME: Why):
+/// - Nullary twines are always represented with their Kind on the left-hand
+/// side, and the Empty kind on the right-hand side.
+/// - Unary twines are always represented with the value on the left-hand
+/// side, and the Empty kind on the right-hand side.
+/// - If a Twine has another Twine as a child, that child should always be
+/// binary (otherwise it could have been folded into the parent).
+///
+/// These invariants are check by \see isValid().
+///
+/// \b Efficiency Considerations
+///
+/// The Twine is designed to yield efficient and small code for common
+/// situations. For this reason, the concat() method is inlined so that
+/// concatenations of leaf nodes can be optimized into stores directly into a
+/// single stack allocated object.
+///
+/// In practice, not all compilers can be trusted to optimize concat() fully,
+/// so we provide two additional methods (and accompanying operator+
+/// overloads) to guarantee that particularly important cases (cstring plus
+/// StringRef) codegen as desired.
+class Twine {
+ /// NodeKind - Represent the type of an argument.
+ enum NodeKind : unsigned char {
+ /// An empty string; the result of concatenating anything with it is also
+ /// empty.
+ NullKind,
+
+ /// The empty string.
+ EmptyKind,
+
+ /// A pointer to a Twine instance.
+ TwineKind,
+
+ /// A pointer to a C string instance.
+ CStringKind,
+
+ /// A pointer to an std::string instance.
+ StdStringKind,
+
+ /// A Pointer and Length representation. Used for std::string_view,
+ /// StringRef, and SmallString. Can't use a StringRef here
+ /// because they are not trivally constructible.
+ PtrAndLengthKind,
+
+ /// A pointer and length representation that's also null-terminated.
+ /// Guaranteed to be constructed from a compile-time string literal.
+ StringLiteralKind,
+
+ /// A pointer to a formatv_object_base instance.
+ FormatvObjectKind,
+
+ /// A char value, to render as a character.
+ CharKind,
+
+ /// An unsigned int value, to render as an unsigned decimal integer.
+ DecUIKind,
+
+ /// An int value, to render as a signed decimal integer.
+ DecIKind,
+
+ /// A pointer to an unsigned long value, to render as an unsigned decimal
+ /// integer.
+ DecULKind,
+
+ /// A pointer to a long value, to render as a signed decimal integer.
+ DecLKind,
+
+ /// A pointer to an unsigned long long value, to render as an unsigned
+ /// decimal integer.
+ DecULLKind,
+
+ /// A pointer to a long long value, to render as a signed decimal integer.
+ DecLLKind,
+
+ /// A pointer to a uint64_t value, to render as an unsigned hexadecimal
+ /// integer.
+ UHexKind
+ };
- /// Twine - A lightweight data structure for efficiently representing the
- /// concatenation of temporary values as strings.
- ///
- /// A Twine is a kind of rope, it represents a concatenated string using a
- /// binary-tree, where the string is the preorder of the nodes. Since the
- /// Twine can be efficiently rendered into a buffer when its result is used,
- /// it avoids the cost of generating temporary values for intermediate string
- /// results -- particularly in cases when the Twine result is never
- /// required. By explicitly tracking the type of leaf nodes, we can also avoid
- /// the creation of temporary strings for conversions operations (such as
- /// appending an integer to a string).
- ///
- /// A Twine is not intended for use directly and should not be stored, its
- /// implementation relies on the ability to store pointers to temporary stack
- /// objects which may be deallocated at the end of a statement. Twines should
- /// only be used as const references in arguments, when an API wishes
- /// to accept possibly-concatenated strings.
- ///
- /// Twines support a special 'null' value, which always concatenates to form
- /// itself, and renders as an empty string. This can be returned from APIs to
- /// effectively nullify any concatenations performed on the result.
- ///
- /// \b Implementation
- ///
- /// Given the nature of a Twine, it is not possible for the Twine's
- /// concatenation method to construct interior nodes; the result must be
- /// represented inside the returned value. For this reason a Twine object
- /// actually holds two values, the left- and right-hand sides of a
- /// concatenation. We also have nullary Twine objects, which are effectively
- /// sentinel values that represent empty strings.
- ///
- /// Thus, a Twine can effectively have zero, one, or two children. The \see
- /// isNullary(), \see isUnary(), and \see isBinary() predicates exist for
- /// testing the number of children.
- ///
- /// We maintain a number of invariants on Twine objects (FIXME: Why):
- /// - Nullary twines are always represented with their Kind on the left-hand
- /// side, and the Empty kind on the right-hand side.
- /// - Unary twines are always represented with the value on the left-hand
- /// side, and the Empty kind on the right-hand side.
- /// - If a Twine has another Twine as a child, that child should always be
- /// binary (otherwise it could have been folded into the parent).
- ///
- /// These invariants are check by \see isValid().
- ///
- /// \b Efficiency Considerations
- ///
- /// The Twine is designed to yield efficient and small code for common
- /// situations. For this reason, the concat() method is inlined so that
- /// concatenations of leaf nodes can be optimized into stores directly into a
- /// single stack allocated object.
- ///
- /// In practice, not all compilers can be trusted to optimize concat() fully,
- /// so we provide two additional methods (and accompanying operator+
- /// overloads) to guarantee that particularly important cases (cstring plus
- /// StringRef) codegen as desired.
- class Twine {
- /// NodeKind - Represent the type of an argument.
- enum NodeKind : unsigned char {
- /// An empty string; the result of concatenating anything with it is also
- /// empty.
- NullKind,
-
- /// The empty string.
- EmptyKind,
-
- /// A pointer to a Twine instance.
- TwineKind,
-
- /// A pointer to a C string instance.
- CStringKind,
-
- /// A pointer to an std::string instance.
- StdStringKind,
-
- /// A Pointer and Length representation. Used for std::string_view,
- /// StringRef, and SmallString. Can't use a StringRef here
- /// because they are not trivally constructible.
- PtrAndLengthKind,
-
- /// A pointer and length representation that's also null-terminated.
- /// Guaranteed to be constructed from a compile-time string literal.
- StringLiteralKind,
-
- /// A pointer to a formatv_object_base instance.
- FormatvObjectKind,
-
- /// A char value, to render as a character.
- CharKind,
-
- /// An unsigned int value, to render as an unsigned decimal integer.
- DecUIKind,
-
- /// An int value, to render as a signed decimal integer.
- DecIKind,
-
- /// A pointer to an unsigned long value, to render as an unsigned decimal
- /// integer.
- DecULKind,
-
- /// A pointer to a long value, to render as a signed decimal integer.
- DecLKind,
-
- /// A pointer to an unsigned long long value, to render as an unsigned
- /// decimal integer.
- DecULLKind,
-
- /// A pointer to a long long value, to render as a signed decimal integer.
- DecLLKind,
-
- /// A pointer to a uint64_t value, to render as an unsigned hexadecimal
- /// integer.
- UHexKind
- };
-
- union Child
- {
- const Twine *twine;
- const char *cString;
- const std::string *stdString;
- struct {
- const char *ptr;
- size_t length;
- } ptrAndLength;
- const formatv_object_base *formatvObject;
- char character;
- unsigned int decUI;
- int decI;
- const unsigned long *decUL;
- const long *decL;
- const unsigned long long *decULL;
- const long long *decLL;
- const uint64_t *uHex;
- };
-
- /// LHS - The prefix in the concatenation, which may be uninitialized for
- /// Null or Empty kinds.
- Child LHS;
-
- /// RHS - The suffix in the concatenation, which may be uninitialized for
- /// Null or Empty kinds.
- Child RHS;
-
- /// LHSKind - The NodeKind of the left hand side, \see getLHSKind().
- NodeKind LHSKind = EmptyKind;
-
- /// RHSKind - The NodeKind of the right hand side, \see getRHSKind().
- NodeKind RHSKind = EmptyKind;
-
- /// Construct a nullary twine; the kind must be NullKind or EmptyKind.
- explicit Twine(NodeKind Kind) : LHSKind(Kind) {
- assert(isNullary() && "Invalid kind!");
- }
+ union Child {
+ const Twine *twine;
+ const char *cString;
+ const std::string *stdString;
+ struct {
+ const char *ptr;
+ size_t length;
+ } ptrAndLength;
+ const formatv_object_base *formatvObject;
+ char character;
+ unsigned int decUI;
+ int decI;
+ const unsigned long *decUL;
+ const long *decL;
+ const unsigned long long *decULL;
+ const long long *decLL;
+ const uint64_t *uHex;
+ };
- /// Construct a binary twine.
- explicit Twine(const Twine &LHS, const Twine &RHS)
- : LHSKind(TwineKind), RHSKind(TwineKind) {
- this->LHS.twine = &LHS;
- this->RHS.twine = &RHS;
- assert(isValid() && "Invalid twine!");
- }
+ /// LHS - The prefix in the concatenation, which may be uninitialized for
+ /// Null or Empty kinds.
+ Child LHS;
- /// Construct a twine from explicit values.
- explicit Twine(Child LHS, NodeKind LHSKind, Child RHS, NodeKind RHSKind)
- : LHS(LHS), RHS(RHS), LHSKind(LHSKind), RHSKind(RHSKind) {
- assert(isValid() && "Invalid twine!");
- }
+ /// RHS - The suffix in the concatenation, which may be uninitialized for
+ /// Null or Empty kinds.
+ Child RHS;
- /// Check for the null twine.
- bool isNull() const {
- return getLHSKind() == NullKind;
- }
+ /// LHSKind - The NodeKind of the left hand side, \see getLHSKind().
+ NodeKind LHSKind = EmptyKind;
- /// Check for the empty twine.
- bool isEmpty() const {
- return getLHSKind() == EmptyKind;
- }
+ /// RHSKind - The NodeKind of the right hand side, \see getRHSKind().
+ NodeKind RHSKind = EmptyKind;
- /// Check if this is a nullary twine (null or empty).
- bool isNullary() const {
- return isNull() || isEmpty();
- }
+ /// Construct a nullary twine; the kind must be NullKind or EmptyKind.
+ explicit Twine(NodeKind Kind) : LHSKind(Kind) {
+ assert(isNullary() && "Invalid kind!");
+ }
- /// Check if this is a unary twine.
- bool isUnary() const {
- return getRHSKind() == EmptyKind && !isNullary();
- }
+ /// Construct a binary twine.
+ explicit Twine(const Twine &LHS, const Twine &RHS)
+ : LHSKind(TwineKind), RHSKind(TwineKind) {
+ this->LHS.twine = &LHS;
+ this->RHS.twine = &RHS;
+ assert(isValid() && "Invalid twine!");
+ }
- /// Check if this is a binary twine.
- bool isBinary() const {
- return getLHSKind() != NullKind && getRHSKind() != EmptyKind;
- }
+ /// Construct a twine from explicit values.
+ explicit Twine(Child LHS, NodeKind LHSKind, Child RHS, NodeKind RHSKind)
+ : LHS(LHS), RHS(RHS), LHSKind(LHSKind), RHSKind(RHSKind) {
+ assert(isValid() && "Invalid twine!");
+ }
- /// Check if this is a valid twine (satisfying the invariants on
- /// order and number of arguments).
- bool isValid() const {
- // Nullary twines always have Empty on the RHS.
- if (isNullary() && getRHSKind() != EmptyKind)
- return false;
-
- // Null should never appear on the RHS.
- if (getRHSKind() == NullKind)
- return false;
-
- // The RHS cannot be non-empty if the LHS is empty.
- if (getRHSKind() != EmptyKind && getLHSKind() == EmptyKind)
- return false;
-
- // A twine child should always be binary.
- if (getLHSKind() == TwineKind &&
- !LHS.twine->isBinary())
- return false;
- if (getRHSKind() == TwineKind &&
- !RHS.twine->isBinary())
- return false;
+ /// Check for the null twine.
+ bool isNull() const { return getLHSKind() == NullKind; }
- return true;
- }
+ /// Check for the empty twine.
+ bool isEmpty() const { return getLHSKind() == EmptyKind; }
- /// Get the NodeKind of the left-hand side.
- NodeKind getLHSKind() const { return LHSKind; }
+ /// Check if this is a nullary twine (null or empty).
+ bool isNullary() const { return isNull() || isEmpty(); }
- /// Get the NodeKind of the right-hand side.
- NodeKind getRHSKind() const { return RHSKind; }
+ /// Check if this is a unary twine.
+ bool isUnary() const { return getRHSKind() == EmptyKind && !isNullary(); }
- /// Print one child from a twine.
- void printOneChild(raw_ostream &OS, Child Ptr, NodeKind Kind) const;
+ /// Check if this is a binary twine.
+ bool isBinary() const {
+ return getLHSKind() != NullKind && getRHSKind() != EmptyKind;
+ }
- /// Print the representation of one child from a twine.
- void printOneChildRepr(raw_ostream &OS, Child Ptr,
- NodeKind Kind) const;
+ /// Check if this is a valid twine (satisfying the invariants on
+ /// order and number of arguments).
+ bool isValid() const {
+ // Nullary twines always have Empty on the RHS.
+ if (isNullary() && getRHSKind() != EmptyKind)
+ return false;
- public:
- /// @name Constructors
- /// @{
+ // Null should never appear on the RHS.
+ if (getRHSKind() == NullKind)
+ return false;
- /// Construct from an empty string.
- /*implicit*/ Twine() {
- assert(isValid() && "Invalid twine!");
- }
+ // The RHS cannot be non-empty if the LHS is empty.
+ if (getRHSKind() != EmptyKind && getLHSKind() == EmptyKind)
+ return false;
- Twine(const Twine &) = default;
-
- /// Construct from a C string.
- ///
- /// We take care here to optimize "" into the empty twine -- this will be
- /// optimized out for string constants. This allows Twine arguments have
- /// default "" values, without introducing unnecessary string constants.
- /*implicit*/ Twine(const char *Str) {
- if (Str[0] != '\0') {
- LHS.cString = Str;
- LHSKind = CStringKind;
- } else {
- LHSKind = EmptyKind;
- }
-
- assert(isValid() && "Invalid twine!");
- }
- /// Delete the implicit conversion from nullptr as Twine(const char *)
- /// cannot take nullptr.
- /*implicit*/ Twine(std::nullptr_t) = delete;
-
- /// Construct from an std::string.
- /*implicit*/ Twine(const std::string &Str) : LHSKind(StdStringKind) {
- LHS.stdString = &Str;
- assert(isValid() && "Invalid twine!");
- }
+ // A twine child should always be binary.
+ if (getLHSKind() == TwineKind && !LHS.twine->isBinary())
+ return false;
+ if (getRHSKind() == TwineKind && !RHS.twine->isBinary())
+ return false;
- /// 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(PtrAndLengthKind) {
- LHS.ptrAndLength.ptr = Str.data();
- LHS.ptrAndLength.length = Str.length();
- assert(isValid() && "Invalid twine!");
- }
+ return true;
+ }
- /// Construct from a StringRef.
- /*implicit*/ Twine(const StringRef &Str) : LHSKind(PtrAndLengthKind) {
- LHS.ptrAndLength.ptr = Str.data();
- LHS.ptrAndLength.length = Str.size();
- assert(isValid() && "Invalid twine!");
- }
+ /// Get the NodeKind of the left-hand side.
+ NodeKind getLHSKind() const { return LHSKind; }
- /// Construct from a StringLiteral.
- /*implicit*/ Twine(const StringLiteral &Str)
- : LHSKind(StringLiteralKind) {
- LHS.ptrAndLength.ptr = Str.data();
- LHS.ptrAndLength.length = Str.size();
- assert(isValid() && "Invalid twine!");
- }
+ /// Get the NodeKind of the right-hand side.
+ NodeKind getRHSKind() const { return RHSKind; }
- /// Construct from a SmallString.
- /*implicit*/ Twine(const SmallVectorImpl<char> &Str)
- : LHSKind(PtrAndLengthKind) {
- LHS.ptrAndLength.ptr = Str.data();
- LHS.ptrAndLength.length = Str.size();
- assert(isValid() && "Invalid twine!");
- }
+ /// Print one child from a twine.
+ void printOneChild(raw_ostream &OS, Child Ptr, NodeKind Kind) const;
- /// Construct from a formatv_object_base.
- /*implicit*/ Twine(const formatv_object_base &Fmt)
- : LHSKind(FormatvObjectKind) {
- LHS.formatvObject = &Fmt;
- assert(isValid() && "Invalid twine!");
- }
+ /// Print the representation of one child from a twine.
+ void printOneChildRepr(raw_ostream &OS, Child Ptr, NodeKind Kind) const;
- /// Construct from a char.
- explicit Twine(char Val) : LHSKind(CharKind) {
- LHS.character = Val;
- }
+public:
+ /// @name Constructors
+ /// @{
- /// Construct from a signed char.
- explicit Twine(signed char Val) : LHSKind(CharKind) {
- LHS.character = static_cast<char>(Val);
- }
+ /// Construct from an empty string.
+ /*implicit*/ Twine() { assert(isValid() && "Invalid twine!"); }
- /// Construct from an unsigned char.
- explicit Twine(unsigned char Val) : LHSKind(CharKind) {
- LHS.character = static_cast<char>(Val);
- }
+ Twine(const Twine &) = default;
- /// Construct a twine to print \p Val as an unsigned decimal integer.
- explicit Twine(unsigned Val) : LHSKind(DecUIKind) {
- LHS.decUI = Val;
- }
+ /// Construct from a C string.
+ ///
+ /// We take care here to optimize "" into the empty twine -- this will be
+ /// optimized out for string constants. This allows Twine arguments have
+ /// default "" values, without introducing unnecessary string constants.
+ /*implicit*/ Twine(const char *Str) {
+ if (Str[0] != '\0') {
+ LHS.cString = Str;
+ LHSKind = CStringKind;
+ } else {
+ LHSKind = EmptyKind;
+ }
+
+ assert(isValid() && "Invalid twine!");
+ }
+ /// Delete the implicit conversion from nullptr as Twine(const char *)
+ /// cannot take nullptr.
+ /*implicit*/ Twine(std::nullptr_t) = delete;
+
+ /// Construct from an std::string.
+ /*implicit*/ Twine(const std::string &Str) : LHSKind(StdStringKind) {
+ LHS.stdString = &Str;
+ assert(isValid() && "Invalid twine!");
+ }
- /// Construct a twine to print \p Val as a signed decimal integer.
- explicit Twine(int Val) : LHSKind(DecIKind) {
- LHS.decI = Val;
- }
+ /// 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(PtrAndLengthKind) {
+ LHS.ptrAndLength.ptr = Str.data();
+ LHS.ptrAndLength.length = Str.length();
+ assert(isValid() && "Invalid twine!");
+ }
- /// Construct a twine to print \p Val as an unsigned decimal integer.
- explicit Twine(const unsigned long &Val) : LHSKind(DecULKind) {
- LHS.decUL = &Val;
- }
+ /// Construct from a StringRef.
+ /*implicit*/ Twine(const StringRef &Str) : LHSKind(PtrAndLengthKind) {
+ LHS.ptrAndLength.ptr = Str.data();
+ LHS.ptrAndLength.length = Str.size();
+ assert(isValid() && "Invalid twine!");
+ }
- /// Construct a twine to print \p Val as a signed decimal integer.
- explicit Twine(const long &Val) : LHSKind(DecLKind) {
- LHS.decL = &Val;
- }
+ /// Construct from a StringLiteral.
+ /*implicit*/ Twine(const StringLiteral &Str) : LHSKind(StringLiteralKind) {
+ LHS.ptrAndLength.ptr = Str.data();
+ LHS.ptrAndLength.length = Str.size();
+ assert(isValid() && "Invalid twine!");
+ }
- /// Construct a twine to print \p Val as an unsigned decimal integer.
- explicit Twine(const unsigned long long &Val) : LHSKind(DecULLKind) {
- LHS.decULL = &Val;
- }
+ /// Construct from a SmallString.
+ /*implicit*/ Twine(const SmallVectorImpl<char> &Str)
+ : LHSKind(PtrAndLengthKind) {
+ LHS.ptrAndLength.ptr = Str.data();
+ LHS.ptrAndLength.length = Str.size();
+ assert(isValid() && "Invalid twine!");
+ }
- /// Construct a twine to print \p Val as a signed decimal integer.
- explicit Twine(const long long &Val) : LHSKind(DecLLKind) {
- LHS.decLL = &Val;
- }
+ /// Construct from a formatv_object_base.
+ /*implicit*/ Twine(const formatv_object_base &Fmt)
+ : LHSKind(FormatvObjectKind) {
+ LHS.formatvObject = &Fmt;
+ assert(isValid() && "Invalid twine!");
+ }
- // FIXME: Unfortunately, to make sure this is as efficient as possible we
- // need extra binary constructors from particular types. We can't rely on
- // the compiler to be smart enough to fold operator+()/concat() down to the
- // right thing. Yet.
-
- /// Construct as the concatenation of a C string and a StringRef.
- /*implicit*/ Twine(const char *LHS, const StringRef &RHS)
- : LHSKind(CStringKind), RHSKind(PtrAndLengthKind) {
- this->LHS.cString = LHS;
- this->RHS.ptrAndLength.ptr = RHS.data();
- this->RHS.ptrAndLength.length = RHS.size();
- assert(isValid() && "Invalid twine!");
- }
+ /// Construct from a char.
+ explicit Twine(char Val) : LHSKind(CharKind) { LHS.character = Val; }
- /// Construct as the concatenation of a StringRef and a C string.
- /*implicit*/ Twine(const StringRef &LHS, const char *RHS)
- : LHSKind(PtrAndLengthKind), RHSKind(CStringKind) {
- this->LHS.ptrAndLength.ptr = LHS.data();
- this->LHS.ptrAndLength.length = LHS.size();
- this->RHS.cString = RHS;
- assert(isValid() && "Invalid twine!");
- }
+ /// Construct from a signed char.
+ explicit Twine(signed char Val) : LHSKind(CharKind) {
+ LHS.character = static_cast<char>(Val);
+ }
- /// Since the intended use of twines is as temporary objects, assignments
- /// when concatenating might cause undefined behavior or stack corruptions
- Twine &operator=(const Twine &) = delete;
+ /// Construct from an unsigned char.
+ explicit Twine(unsigned char Val) : LHSKind(CharKind) {
+ LHS.character = static_cast<char>(Val);
+ }
- /// Create a 'null' string, which is an empty string that always
- /// concatenates to form another empty string.
- static Twine createNull() {
- return Twine(NullKind);
- }
+ /// Construct a twine to print \p Val as an unsigned decimal integer.
+ explicit Twine(unsigned Val) : LHSKind(DecUIKind) { LHS.decUI = Val; }
- /// @}
- /// @name Numeric Conversions
- /// @{
+ /// Construct a twine to print \p Val as a signed decimal integer.
+ explicit Twine(int Val) : LHSKind(DecIKind) { LHS.decI = Val; }
- // Construct a twine to print \p Val as an unsigned hexadecimal integer.
- static Twine utohexstr(const uint64_t &Val) {
- Child LHS, RHS;
- LHS.uHex = &Val;
- RHS.twine = nullptr;
- return Twine(LHS, UHexKind, RHS, EmptyKind);
- }
+ /// Construct a twine to print \p Val as an unsigned decimal integer.
+ explicit Twine(const unsigned long &Val) : LHSKind(DecULKind) {
+ LHS.decUL = &Val;
+ }
- /// @}
- /// @name Predicate Operations
- /// @{
+ /// Construct a twine to print \p Val as a signed decimal integer.
+ explicit Twine(const long &Val) : LHSKind(DecLKind) { LHS.decL = &Val; }
- /// Check if this twine is trivially empty; a false return value does not
- /// necessarily mean the twine is empty.
- bool isTriviallyEmpty() const {
- return isNullary();
- }
+ /// Construct a twine to print \p Val as an unsigned decimal integer.
+ explicit Twine(const unsigned long long &Val) : LHSKind(DecULLKind) {
+ LHS.decULL = &Val;
+ }
- /// Check if this twine is guaranteed to refer to single string literal.
- bool isSingleStringLiteral() const {
- return isUnary() && getLHSKind() == StringLiteralKind;
- }
+ /// Construct a twine to print \p Val as a signed decimal integer.
+ explicit Twine(const long long &Val) : LHSKind(DecLLKind) {
+ LHS.decLL = &Val;
+ }
- /// Return true if this twine can be dynamically accessed as a single
- /// StringRef value with getSingleStringRef().
- bool isSingleStringRef() const {
- if (getRHSKind() != EmptyKind) return false;
-
- switch (getLHSKind()) {
- case EmptyKind:
- case CStringKind:
- case StdStringKind:
- case PtrAndLengthKind:
- case StringLiteralKind:
- return true;
- default:
- return false;
- }
- }
+ // FIXME: Unfortunately, to make sure this is as efficient as possible we
+ // need extra binary constructors from particular types. We can't rely on
+ // the compiler to be smart enough to fold operator+()/concat() down to the
+ // right thing. Yet.
+
+ /// Construct as the concatenation of a C string and a StringRef.
+ /*implicit*/ Twine(const char *LHS, const StringRef &RHS)
+ : LHSKind(CStringKind), RHSKind(PtrAndLengthKind) {
+ this->LHS.cString = LHS;
+ this->RHS.ptrAndLength.ptr = RHS.data();
+ this->RHS.ptrAndLength.length = RHS.size();
+ assert(isValid() && "Invalid twine!");
+ }
- /// @}
- /// @name String Operations
- /// @{
-
- Twine concat(const Twine &Suffix) const;
-
- /// @}
- /// @name Output & Conversion.
- /// @{
-
- /// Return the twine contents as a std::string.
- LLVM_ABI std::string str() const;
-
- /// Append the concatenated string into the given SmallString or SmallVector.
- LLVM_ABI void toVector(SmallVectorImpl<char> &Out) const;
-
- /// This returns the twine as a single StringRef. This method is only valid
- /// if isSingleStringRef() is true.
- StringRef getSingleStringRef() const {
- assert(isSingleStringRef() &&"This cannot be had as a single stringref!");
- switch (getLHSKind()) {
- default: llvm_unreachable("Out of sync with isSingleStringRef");
- case EmptyKind:
- return StringRef();
- case CStringKind:
- return StringRef(LHS.cString);
- case StdStringKind:
- return StringRef(*LHS.stdString);
- case PtrAndLengthKind:
- case StringLiteralKind:
- return StringRef(LHS.ptrAndLength.ptr, LHS.ptrAndLength.length);
- }
- }
+ /// Construct as the concatenation of a StringRef and a C string.
+ /*implicit*/ Twine(const StringRef &LHS, const char *RHS)
+ : LHSKind(PtrAndLengthKind), RHSKind(CStringKind) {
+ this->LHS.ptrAndLength.ptr = LHS.data();
+ this->LHS.ptrAndLength.length = LHS.size();
+ this->RHS.cString = RHS;
+ assert(isValid() && "Invalid twine!");
+ }
- /// This returns the twine as a single StringRef if it can be
- /// represented as such. Otherwise the twine is written into the given
- /// SmallVector and a StringRef to the SmallVector's data is returned.
- StringRef toStringRef(SmallVectorImpl<char> &Out) const {
- if (isSingleStringRef())
- return getSingleStringRef();
- toVector(Out);
- return StringRef(Out.data(), Out.size());
- }
+ /// Since the intended use of twines is as temporary objects, assignments
+ /// when concatenating might cause undefined behavior or stack corruptions
+ Twine &operator=(const Twine &) = delete;
- /// This returns the twine as a single null terminated StringRef if it
- /// can be represented as such. Otherwise the twine is written into the
- /// given SmallVector and a StringRef to the SmallVector's data is returned.
- ///
- /// The returned StringRef's size does not include the null terminator.
- LLVM_ABI StringRef
- toNullTerminatedStringRef(SmallVectorImpl<char> &Out) const;
+ /// Create a 'null' string, which is an empty string that always
+ /// concatenates to form another empty string.
+ static Twine createNull() { return Twine(NullKind); }
- /// Write the concatenated string represented by this twine to the
- /// stream \p OS.
- LLVM_ABI void print(raw_ostream &OS) const;
+ /// @}
+ /// @name Numeric Conversions
+ /// @{
- /// Write the representation of this twine to the stream \p OS.
- LLVM_ABI void printRepr(raw_ostream &OS) const;
+ // Construct a twine to print \p Val as an unsigned hexadecimal integer.
+ static Twine utohexstr(const uint64_t &Val) {
+ Child LHS, RHS;
+ LHS.uHex = &Val;
+ RHS.twine = nullptr;
+ return Twine(LHS, UHexKind, RHS, EmptyKind);
+ }
-#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
- /// Dump the concatenated string represented by this twine to stderr.
- LLVM_DUMP_METHOD void dump() const;
+ /// @}
+ /// @name Predicate Operations
+ /// @{
- /// Dump the representation of this twine to stderr.
- LLVM_DUMP_METHOD void dumpRepr() const;
-#endif
+ /// Check if this twine is trivially empty; a false return value does not
+ /// necessarily mean the twine is empty.
+ bool isTriviallyEmpty() const { return isNullary(); }
- /// @}
- };
+ /// Check if this twine is guaranteed to refer to single string literal.
+ bool isSingleStringLiteral() const {
+ return isUnary() && getLHSKind() == StringLiteralKind;
+ }
- /// @name Twine Inline Implementations
+ /// Return true if this twine can be dynamically accessed as a single
+ /// StringRef value with getSingleStringRef().
+ bool isSingleStringRef() const {
+ if (getRHSKind() != EmptyKind)
+ return false;
+
+ switch (getLHSKind()) {
+ case EmptyKind:
+ case CStringKind:
+ case StdStringKind:
+ case PtrAndLengthKind:
+ case StringLiteralKind:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ /// @}
+ /// @name String Operations
/// @{
- inline Twine Twine::concat(const Twine &Suffix) const {
- // Concatenation with null is null.
- if (isNull() || Suffix.isNull())
- return Twine(NullKind);
-
- // Concatenation with empty yields the other side.
- if (isEmpty())
- return Suffix;
- if (Suffix.isEmpty())
- return *this;
-
- // Otherwise we need to create a new node, taking care to fold in unary
- // twines.
- Child NewLHS, NewRHS;
- NewLHS.twine = this;
- NewRHS.twine = &Suffix;
- NodeKind NewLHSKind = TwineKind, NewRHSKind = TwineKind;
- if (isUnary()) {
- NewLHS = LHS;
- NewLHSKind = getLHSKind();
- }
- if (Suffix.isUnary()) {
- NewRHS = Suffix.LHS;
- NewRHSKind = Suffix.getLHSKind();
- }
+ Twine concat(const Twine &Suffix) const;
- return Twine(NewLHS, NewLHSKind, NewRHS, NewRHSKind);
+ /// @}
+ /// @name Output & Conversion.
+ /// @{
+
+ /// Return the twine contents as a std::string.
+ LLVM_ABI std::string str() const;
+
+ /// Append the concatenated string into the given SmallString or SmallVector.
+ LLVM_ABI void toVector(SmallVectorImpl<char> &Out) const;
+
+ /// This returns the twine as a single StringRef. This method is only valid
+ /// if isSingleStringRef() is true.
+ StringRef getSingleStringRef() const {
+ assert(isSingleStringRef() && "This cannot be had as a single stringref!");
+ switch (getLHSKind()) {
+ default:
+ llvm_unreachable("Out of sync with isSingleStringRef");
+ case EmptyKind:
+ return StringRef();
+ case CStringKind:
+ return StringRef(LHS.cString);
+ case StdStringKind:
+ return StringRef(*LHS.stdString);
+ case PtrAndLengthKind:
+ case StringLiteralKind:
+ return StringRef(LHS.ptrAndLength.ptr, LHS.ptrAndLength.length);
+ }
}
- inline Twine operator+(const Twine &LHS, const Twine &RHS) {
- return LHS.concat(RHS);
+ /// This returns the twine as a single StringRef if it can be
+ /// represented as such. Otherwise the twine is written into the given
+ /// SmallVector and a StringRef to the SmallVector's data is returned.
+ StringRef toStringRef(SmallVectorImpl<char> &Out) const {
+ if (isSingleStringRef())
+ return getSingleStringRef();
+ toVector(Out);
+ return StringRef(Out.data(), Out.size());
}
- /// Additional overload to guarantee simplified codegen; this is equivalent to
- /// concat().
+ /// This returns the twine as a single null terminated StringRef if it
+ /// can be represented as such. Otherwise the twine is written into the
+ /// given SmallVector and a StringRef to the SmallVector's data is returned.
+ ///
+ /// The returned StringRef's size does not include the null terminator.
+ LLVM_ABI StringRef
+ toNullTerminatedStringRef(SmallVectorImpl<char> &Out) const;
- inline Twine operator+(const char *LHS, const StringRef &RHS) {
- return Twine(LHS, RHS);
- }
+ /// Write the concatenated string represented by this twine to the
+ /// stream \p OS.
+ LLVM_ABI void print(raw_ostream &OS) const;
- /// Additional overload to guarantee simplified codegen; this is equivalent to
- /// concat().
+ /// Write the representation of this twine to the stream \p OS.
+ LLVM_ABI void printRepr(raw_ostream &OS) const;
- inline Twine operator+(const StringRef &LHS, const char *RHS) {
- return Twine(LHS, RHS);
- }
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+ /// Dump the concatenated string represented by this twine to stderr.
+ LLVM_DUMP_METHOD void dump() const;
- inline raw_ostream &operator<<(raw_ostream &OS, const Twine &RHS) {
- RHS.print(OS);
- return OS;
- }
+ /// Dump the representation of this twine to stderr.
+ LLVM_DUMP_METHOD void dumpRepr() const;
+#endif
/// @}
+};
+
+/// @name Twine Inline Implementations
+/// @{
+
+inline Twine Twine::concat(const Twine &Suffix) const {
+ // Concatenation with null is null.
+ if (isNull() || Suffix.isNull())
+ return Twine(NullKind);
+
+ // Concatenation with empty yields the other side.
+ if (isEmpty())
+ return Suffix;
+ if (Suffix.isEmpty())
+ return *this;
+
+ // Otherwise we need to create a new node, taking care to fold in unary
+ // twines.
+ Child NewLHS, NewRHS;
+ NewLHS.twine = this;
+ NewRHS.twine = &Suffix;
+ NodeKind NewLHSKind = TwineKind, NewRHSKind = TwineKind;
+ if (isUnary()) {
+ NewLHS = LHS;
+ NewLHSKind = getLHSKind();
+ }
+ if (Suffix.isUnary()) {
+ NewRHS = Suffix.LHS;
+ NewRHSKind = Suffix.getLHSKind();
+ }
+
+ return Twine(NewLHS, NewLHSKind, NewRHS, NewRHSKind);
+}
+
+inline Twine operator+(const Twine &LHS, const Twine &RHS) {
+ return LHS.concat(RHS);
+}
+
+/// Additional overload to guarantee simplified codegen; this is equivalent to
+/// concat().
+
+inline Twine operator+(const char *LHS, const StringRef &RHS) {
+ return Twine(LHS, RHS);
+}
+
+/// Additional overload to guarantee simplified codegen; this is equivalent to
+/// concat().
+
+inline Twine operator+(const StringRef &LHS, const char *RHS) {
+ return Twine(LHS, RHS);
+}
+
+inline raw_ostream &operator<<(raw_ostream &OS, const Twine &RHS) {
+ RHS.print(OS);
+ return OS;
+}
+
+/// @}
} // end namespace llvm
diff --git a/llvm/lib/Support/Twine.cpp b/llvm/lib/Support/Twine.cpp
index 495b9cf2dbd68..d6b48166fb0f6 100644
--- a/llvm/lib/Support/Twine.cpp
+++ b/llvm/lib/Support/Twine.cpp
@@ -56,11 +56,12 @@ StringRef Twine::toNullTerminatedStringRef(SmallVectorImpl<char> &Out) const {
return StringRef(Out.data(), Out.size());
}
-void Twine::printOneChild(raw_ostream &OS, Child Ptr,
- NodeKind Kind) const {
+void Twine::printOneChild(raw_ostream &OS, Child Ptr, NodeKind Kind) const {
switch (Kind) {
- case Twine::NullKind: break;
- case Twine::EmptyKind: break;
+ case Twine::NullKind:
+ break;
+ case Twine::EmptyKind:
+ break;
case Twine::TwineKind:
Ptr.twine->print(OS);
break;
@@ -104,24 +105,23 @@ void Twine::printOneChild(raw_ostream &OS, Child Ptr,
}
}
-void Twine::printOneChildRepr(raw_ostream &OS, Child Ptr,
- NodeKind Kind) const {
+void Twine::printOneChildRepr(raw_ostream &OS, Child Ptr, NodeKind Kind) const {
switch (Kind) {
case Twine::NullKind:
- OS << "null"; break;
+ OS << "null";
+ break;
case Twine::EmptyKind:
- OS << "empty"; break;
+ OS << "empty";
+ break;
case Twine::TwineKind:
OS << "rope:";
Ptr.twine->printRepr(OS);
break;
case Twine::CStringKind:
- OS << "cstring:\""
- << Ptr.cString << "\"";
+ OS << "cstring:\"" << Ptr.cString << "\"";
break;
case Twine::StdStringKind:
- OS << "std::string:\""
- << Ptr.stdString << "\"";
+ OS << "std::string:\"" << Ptr.stdString << "\"";
break;
case Twine::PtrAndLengthKind:
OS << "ptrAndLength:\""
@@ -175,11 +175,7 @@ void Twine::printRepr(raw_ostream &OS) const {
}
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
-LLVM_DUMP_METHOD void Twine::dump() const {
- print(dbgs());
-}
+LLVM_DUMP_METHOD void Twine::dump() const { print(dbgs()); }
-LLVM_DUMP_METHOD void Twine::dumpRepr() const {
- printRepr(dbgs());
-}
+LLVM_DUMP_METHOD void Twine::dumpRepr() const { printRepr(dbgs()); }
#endif
More information about the llvm-commits
mailing list