1327952Sdim//===- Twine.h - Fast Temporary String Concatenation ------------*- C++ -*-===// 2198090Srdivacky// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6198090Srdivacky// 7198090Srdivacky//===----------------------------------------------------------------------===// 8198090Srdivacky 9198090Srdivacky#ifndef LLVM_ADT_TWINE_H 10198090Srdivacky#define LLVM_ADT_TWINE_H 11198090Srdivacky 12288943Sdim#include "llvm/ADT/SmallVector.h" 13198090Srdivacky#include "llvm/ADT/StringRef.h" 14234353Sdim#include "llvm/Support/ErrorHandling.h" 15198090Srdivacky#include <cassert> 16314564Sdim#include <cstdint> 17198090Srdivacky#include <string> 18198090Srdivacky 19198090Srdivackynamespace llvm { 20314564Sdim 21314564Sdim class formatv_object_base; 22198090Srdivacky class raw_ostream; 23198090Srdivacky 24198090Srdivacky /// Twine - A lightweight data structure for efficiently representing the 25198090Srdivacky /// concatenation of temporary values as strings. 26198090Srdivacky /// 27198090Srdivacky /// A Twine is a kind of rope, it represents a concatenated string using a 28198090Srdivacky /// binary-tree, where the string is the preorder of the nodes. Since the 29198090Srdivacky /// Twine can be efficiently rendered into a buffer when its result is used, 30198090Srdivacky /// it avoids the cost of generating temporary values for intermediate string 31198090Srdivacky /// results -- particularly in cases when the Twine result is never 32198090Srdivacky /// required. By explicitly tracking the type of leaf nodes, we can also avoid 33198090Srdivacky /// the creation of temporary strings for conversions operations (such as 34198090Srdivacky /// appending an integer to a string). 35198090Srdivacky /// 36198090Srdivacky /// A Twine is not intended for use directly and should not be stored, its 37198090Srdivacky /// implementation relies on the ability to store pointers to temporary stack 38198090Srdivacky /// objects which may be deallocated at the end of a statement. Twines should 39198090Srdivacky /// only be used accepted as const references in arguments, when an API wishes 40198090Srdivacky /// to accept possibly-concatenated strings. 41198090Srdivacky /// 42198090Srdivacky /// Twines support a special 'null' value, which always concatenates to form 43198090Srdivacky /// itself, and renders as an empty string. This can be returned from APIs to 44198090Srdivacky /// effectively nullify any concatenations performed on the result. 45218893Sdim /// 46243830Sdim /// \b Implementation 47198090Srdivacky /// 48198090Srdivacky /// Given the nature of a Twine, it is not possible for the Twine's 49198090Srdivacky /// concatenation method to construct interior nodes; the result must be 50198090Srdivacky /// represented inside the returned value. For this reason a Twine object 51198090Srdivacky /// actually holds two values, the left- and right-hand sides of a 52198090Srdivacky /// concatenation. We also have nullary Twine objects, which are effectively 53198090Srdivacky /// sentinel values that represent empty strings. 54198090Srdivacky /// 55198090Srdivacky /// Thus, a Twine can effectively have zero, one, or two children. The \see 56198090Srdivacky /// isNullary(), \see isUnary(), and \see isBinary() predicates exist for 57198090Srdivacky /// testing the number of children. 58198090Srdivacky /// 59198090Srdivacky /// We maintain a number of invariants on Twine objects (FIXME: Why): 60198090Srdivacky /// - Nullary twines are always represented with their Kind on the left-hand 61198090Srdivacky /// side, and the Empty kind on the right-hand side. 62198090Srdivacky /// - Unary twines are always represented with the value on the left-hand 63198090Srdivacky /// side, and the Empty kind on the right-hand side. 64198090Srdivacky /// - If a Twine has another Twine as a child, that child should always be 65198090Srdivacky /// binary (otherwise it could have been folded into the parent). 66198090Srdivacky /// 67198090Srdivacky /// These invariants are check by \see isValid(). 68198090Srdivacky /// 69243830Sdim /// \b Efficiency Considerations 70198090Srdivacky /// 71198090Srdivacky /// The Twine is designed to yield efficient and small code for common 72198090Srdivacky /// situations. For this reason, the concat() method is inlined so that 73198090Srdivacky /// concatenations of leaf nodes can be optimized into stores directly into a 74198090Srdivacky /// single stack allocated object. 75198090Srdivacky /// 76198090Srdivacky /// In practice, not all compilers can be trusted to optimize concat() fully, 77198090Srdivacky /// so we provide two additional methods (and accompanying operator+ 78198090Srdivacky /// overloads) to guarantee that particularly important cases (cstring plus 79198090Srdivacky /// StringRef) codegen as desired. 80198090Srdivacky class Twine { 81198090Srdivacky /// NodeKind - Represent the type of an argument. 82280031Sdim enum NodeKind : unsigned char { 83198090Srdivacky /// An empty string; the result of concatenating anything with it is also 84198090Srdivacky /// empty. 85198090Srdivacky NullKind, 86198090Srdivacky 87198090Srdivacky /// The empty string. 88198090Srdivacky EmptyKind, 89198090Srdivacky 90198090Srdivacky /// A pointer to a Twine instance. 91198090Srdivacky TwineKind, 92198090Srdivacky 93198090Srdivacky /// A pointer to a C string instance. 94198090Srdivacky CStringKind, 95198090Srdivacky 96198090Srdivacky /// A pointer to an std::string instance. 97198090Srdivacky StdStringKind, 98198090Srdivacky 99198090Srdivacky /// A pointer to a StringRef instance. 100198090Srdivacky StringRefKind, 101198090Srdivacky 102288943Sdim /// A pointer to a SmallString instance. 103288943Sdim SmallStringKind, 104288943Sdim 105314564Sdim /// A pointer to a formatv_object_base instance. 106314564Sdim FormatvObjectKind, 107314564Sdim 108296417Sdim /// A char value, to render as a character. 109226633Sdim CharKind, 110226633Sdim 111296417Sdim /// An unsigned int value, to render as an unsigned decimal integer. 112198090Srdivacky DecUIKind, 113198090Srdivacky 114296417Sdim /// An int value, to render as a signed decimal integer. 115198090Srdivacky DecIKind, 116198090Srdivacky 117198090Srdivacky /// A pointer to an unsigned long value, to render as an unsigned decimal 118198090Srdivacky /// integer. 119198090Srdivacky DecULKind, 120198090Srdivacky 121198090Srdivacky /// A pointer to a long value, to render as a signed decimal integer. 122198090Srdivacky DecLKind, 123198090Srdivacky 124198090Srdivacky /// A pointer to an unsigned long long value, to render as an unsigned 125198090Srdivacky /// decimal integer. 126198090Srdivacky DecULLKind, 127198090Srdivacky 128198090Srdivacky /// A pointer to a long long value, to render as a signed decimal integer. 129198090Srdivacky DecLLKind, 130198090Srdivacky 131198090Srdivacky /// A pointer to a uint64_t value, to render as an unsigned hexadecimal 132198090Srdivacky /// integer. 133198090Srdivacky UHexKind 134198090Srdivacky }; 135198090Srdivacky 136226633Sdim union Child 137226633Sdim { 138226633Sdim const Twine *twine; 139226633Sdim const char *cString; 140226633Sdim const std::string *stdString; 141226633Sdim const StringRef *stringRef; 142288943Sdim const SmallVectorImpl<char> *smallString; 143314564Sdim const formatv_object_base *formatvObject; 144226633Sdim char character; 145226633Sdim unsigned int decUI; 146226633Sdim int decI; 147226633Sdim const unsigned long *decUL; 148226633Sdim const long *decL; 149226633Sdim const unsigned long long *decULL; 150226633Sdim const long long *decLL; 151226633Sdim const uint64_t *uHex; 152226633Sdim }; 153226633Sdim 154198090Srdivacky /// LHS - The prefix in the concatenation, which may be uninitialized for 155198090Srdivacky /// Null or Empty kinds. 156360784Sdim Child LHS = {0}; 157327952Sdim 158198090Srdivacky /// RHS - The suffix in the concatenation, which may be uninitialized for 159198090Srdivacky /// Null or Empty kinds. 160360784Sdim Child RHS = {0}; 161327952Sdim 162198090Srdivacky /// LHSKind - The NodeKind of the left hand side, \see getLHSKind(). 163327952Sdim NodeKind LHSKind = EmptyKind; 164327952Sdim 165280031Sdim /// RHSKind - The NodeKind of the right hand side, \see getRHSKind(). 166327952Sdim NodeKind RHSKind = EmptyKind; 167198090Srdivacky 168198090Srdivacky /// Construct a nullary twine; the kind must be NullKind or EmptyKind. 169327952Sdim explicit Twine(NodeKind Kind) : LHSKind(Kind) { 170198090Srdivacky assert(isNullary() && "Invalid kind!"); 171198090Srdivacky } 172198090Srdivacky 173198090Srdivacky /// Construct a binary twine. 174288943Sdim explicit Twine(const Twine &LHS, const Twine &RHS) 175288943Sdim : LHSKind(TwineKind), RHSKind(TwineKind) { 176288943Sdim this->LHS.twine = &LHS; 177288943Sdim this->RHS.twine = &RHS; 178198090Srdivacky assert(isValid() && "Invalid twine!"); 179198090Srdivacky } 180198090Srdivacky 181198090Srdivacky /// Construct a twine from explicit values. 182288943Sdim explicit Twine(Child LHS, NodeKind LHSKind, Child RHS, NodeKind RHSKind) 183288943Sdim : LHS(LHS), RHS(RHS), LHSKind(LHSKind), RHSKind(RHSKind) { 184198090Srdivacky assert(isValid() && "Invalid twine!"); 185198090Srdivacky } 186198090Srdivacky 187288943Sdim /// Check for the null twine. 188198090Srdivacky bool isNull() const { 189198090Srdivacky return getLHSKind() == NullKind; 190198090Srdivacky } 191198090Srdivacky 192288943Sdim /// Check for the empty twine. 193198090Srdivacky bool isEmpty() const { 194198090Srdivacky return getLHSKind() == EmptyKind; 195198090Srdivacky } 196198090Srdivacky 197288943Sdim /// Check if this is a nullary twine (null or empty). 198198090Srdivacky bool isNullary() const { 199198090Srdivacky return isNull() || isEmpty(); 200198090Srdivacky } 201198090Srdivacky 202288943Sdim /// Check if this is a unary twine. 203198090Srdivacky bool isUnary() const { 204198090Srdivacky return getRHSKind() == EmptyKind && !isNullary(); 205198090Srdivacky } 206198090Srdivacky 207288943Sdim /// Check if this is a binary twine. 208198090Srdivacky bool isBinary() const { 209198090Srdivacky return getLHSKind() != NullKind && getRHSKind() != EmptyKind; 210198090Srdivacky } 211198090Srdivacky 212288943Sdim /// Check if this is a valid twine (satisfying the invariants on 213198090Srdivacky /// order and number of arguments). 214198090Srdivacky bool isValid() const { 215198090Srdivacky // Nullary twines always have Empty on the RHS. 216198090Srdivacky if (isNullary() && getRHSKind() != EmptyKind) 217198090Srdivacky return false; 218198090Srdivacky 219198090Srdivacky // Null should never appear on the RHS. 220198090Srdivacky if (getRHSKind() == NullKind) 221198090Srdivacky return false; 222198090Srdivacky 223198090Srdivacky // The RHS cannot be non-empty if the LHS is empty. 224198090Srdivacky if (getRHSKind() != EmptyKind && getLHSKind() == EmptyKind) 225198090Srdivacky return false; 226198090Srdivacky 227198090Srdivacky // A twine child should always be binary. 228198090Srdivacky if (getLHSKind() == TwineKind && 229226633Sdim !LHS.twine->isBinary()) 230198090Srdivacky return false; 231198090Srdivacky if (getRHSKind() == TwineKind && 232226633Sdim !RHS.twine->isBinary()) 233198090Srdivacky return false; 234198090Srdivacky 235198090Srdivacky return true; 236198090Srdivacky } 237198090Srdivacky 238288943Sdim /// Get the NodeKind of the left-hand side. 239280031Sdim NodeKind getLHSKind() const { return LHSKind; } 240198090Srdivacky 241288943Sdim /// Get the NodeKind of the right-hand side. 242280031Sdim NodeKind getRHSKind() const { return RHSKind; } 243198090Srdivacky 244288943Sdim /// Print one child from a twine. 245226633Sdim void printOneChild(raw_ostream &OS, Child Ptr, NodeKind Kind) const; 246198090Srdivacky 247288943Sdim /// Print the representation of one child from a twine. 248226633Sdim void printOneChildRepr(raw_ostream &OS, Child Ptr, 249198090Srdivacky NodeKind Kind) const; 250198090Srdivacky 251198090Srdivacky public: 252198090Srdivacky /// @name Constructors 253198090Srdivacky /// @{ 254198090Srdivacky 255198090Srdivacky /// Construct from an empty string. 256327952Sdim /*implicit*/ Twine() { 257198090Srdivacky assert(isValid() && "Invalid twine!"); 258198090Srdivacky } 259198090Srdivacky 260288943Sdim Twine(const Twine &) = default; 261288943Sdim 262198090Srdivacky /// Construct from a C string. 263198090Srdivacky /// 264198090Srdivacky /// We take care here to optimize "" into the empty twine -- this will be 265198090Srdivacky /// optimized out for string constants. This allows Twine arguments have 266198090Srdivacky /// default "" values, without introducing unnecessary string constants. 267327952Sdim /*implicit*/ Twine(const char *Str) { 268198090Srdivacky if (Str[0] != '\0') { 269226633Sdim LHS.cString = Str; 270198090Srdivacky LHSKind = CStringKind; 271198090Srdivacky } else 272198090Srdivacky LHSKind = EmptyKind; 273198090Srdivacky 274198090Srdivacky assert(isValid() && "Invalid twine!"); 275198090Srdivacky } 276353358Sdim /// Delete the implicit conversion from nullptr as Twine(const char *) 277353358Sdim /// cannot take nullptr. 278353358Sdim /*implicit*/ Twine(std::nullptr_t) = delete; 279198090Srdivacky 280198090Srdivacky /// Construct from an std::string. 281327952Sdim /*implicit*/ Twine(const std::string &Str) : LHSKind(StdStringKind) { 282226633Sdim LHS.stdString = &Str; 283198090Srdivacky assert(isValid() && "Invalid twine!"); 284198090Srdivacky } 285198090Srdivacky 286198090Srdivacky /// Construct from a StringRef. 287327952Sdim /*implicit*/ Twine(const StringRef &Str) : LHSKind(StringRefKind) { 288226633Sdim LHS.stringRef = &Str; 289198090Srdivacky assert(isValid() && "Invalid twine!"); 290198090Srdivacky } 291198090Srdivacky 292288943Sdim /// Construct from a SmallString. 293288943Sdim /*implicit*/ Twine(const SmallVectorImpl<char> &Str) 294327952Sdim : LHSKind(SmallStringKind) { 295288943Sdim LHS.smallString = &Str; 296288943Sdim assert(isValid() && "Invalid twine!"); 297288943Sdim } 298288943Sdim 299314564Sdim /// Construct from a formatv_object_base. 300314564Sdim /*implicit*/ Twine(const formatv_object_base &Fmt) 301327952Sdim : LHSKind(FormatvObjectKind) { 302314564Sdim LHS.formatvObject = &Fmt; 303314564Sdim assert(isValid() && "Invalid twine!"); 304314564Sdim } 305314564Sdim 306226633Sdim /// Construct from a char. 307327952Sdim explicit Twine(char Val) : LHSKind(CharKind) { 308226633Sdim LHS.character = Val; 309226633Sdim } 310226633Sdim 311226633Sdim /// Construct from a signed char. 312327952Sdim explicit Twine(signed char Val) : LHSKind(CharKind) { 313226633Sdim LHS.character = static_cast<char>(Val); 314226633Sdim } 315226633Sdim 316226633Sdim /// Construct from an unsigned char. 317327952Sdim explicit Twine(unsigned char Val) : LHSKind(CharKind) { 318226633Sdim LHS.character = static_cast<char>(Val); 319226633Sdim } 320226633Sdim 321243830Sdim /// Construct a twine to print \p Val as an unsigned decimal integer. 322327952Sdim explicit Twine(unsigned Val) : LHSKind(DecUIKind) { 323226633Sdim LHS.decUI = Val; 324198090Srdivacky } 325198090Srdivacky 326243830Sdim /// Construct a twine to print \p Val as a signed decimal integer. 327327952Sdim explicit Twine(int Val) : LHSKind(DecIKind) { 328226633Sdim LHS.decI = Val; 329198090Srdivacky } 330198090Srdivacky 331243830Sdim /// Construct a twine to print \p Val as an unsigned decimal integer. 332327952Sdim explicit Twine(const unsigned long &Val) : LHSKind(DecULKind) { 333226633Sdim LHS.decUL = &Val; 334198090Srdivacky } 335198090Srdivacky 336243830Sdim /// Construct a twine to print \p Val as a signed decimal integer. 337327952Sdim explicit Twine(const long &Val) : LHSKind(DecLKind) { 338226633Sdim LHS.decL = &Val; 339198090Srdivacky } 340198090Srdivacky 341243830Sdim /// Construct a twine to print \p Val as an unsigned decimal integer. 342327952Sdim explicit Twine(const unsigned long long &Val) : LHSKind(DecULLKind) { 343226633Sdim LHS.decULL = &Val; 344198090Srdivacky } 345198090Srdivacky 346243830Sdim /// Construct a twine to print \p Val as a signed decimal integer. 347327952Sdim explicit Twine(const long long &Val) : LHSKind(DecLLKind) { 348226633Sdim LHS.decLL = &Val; 349198090Srdivacky } 350198090Srdivacky 351198090Srdivacky // FIXME: Unfortunately, to make sure this is as efficient as possible we 352198090Srdivacky // need extra binary constructors from particular types. We can't rely on 353198090Srdivacky // the compiler to be smart enough to fold operator+()/concat() down to the 354198090Srdivacky // right thing. Yet. 355198090Srdivacky 356198090Srdivacky /// Construct as the concatenation of a C string and a StringRef. 357288943Sdim /*implicit*/ Twine(const char *LHS, const StringRef &RHS) 358288943Sdim : LHSKind(CStringKind), RHSKind(StringRefKind) { 359288943Sdim this->LHS.cString = LHS; 360288943Sdim this->RHS.stringRef = &RHS; 361198090Srdivacky assert(isValid() && "Invalid twine!"); 362198090Srdivacky } 363198090Srdivacky 364198090Srdivacky /// Construct as the concatenation of a StringRef and a C string. 365288943Sdim /*implicit*/ Twine(const StringRef &LHS, const char *RHS) 366288943Sdim : LHSKind(StringRefKind), RHSKind(CStringKind) { 367288943Sdim this->LHS.stringRef = &LHS; 368288943Sdim this->RHS.cString = RHS; 369198090Srdivacky assert(isValid() && "Invalid twine!"); 370198090Srdivacky } 371198090Srdivacky 372314564Sdim /// Since the intended use of twines is as temporary objects, assignments 373314564Sdim /// when concatenating might cause undefined behavior or stack corruptions 374314564Sdim Twine &operator=(const Twine &) = delete; 375314564Sdim 376198090Srdivacky /// Create a 'null' string, which is an empty string that always 377198090Srdivacky /// concatenates to form another empty string. 378198090Srdivacky static Twine createNull() { 379198090Srdivacky return Twine(NullKind); 380198090Srdivacky } 381198090Srdivacky 382198090Srdivacky /// @} 383198090Srdivacky /// @name Numeric Conversions 384198090Srdivacky /// @{ 385198090Srdivacky 386243830Sdim // Construct a twine to print \p Val as an unsigned hexadecimal integer. 387198090Srdivacky static Twine utohexstr(const uint64_t &Val) { 388226633Sdim Child LHS, RHS; 389226633Sdim LHS.uHex = &Val; 390276479Sdim RHS.twine = nullptr; 391226633Sdim return Twine(LHS, UHexKind, RHS, EmptyKind); 392198090Srdivacky } 393198090Srdivacky 394198090Srdivacky /// @} 395198090Srdivacky /// @name Predicate Operations 396198090Srdivacky /// @{ 397198090Srdivacky 398288943Sdim /// Check if this twine is trivially empty; a false return value does not 399288943Sdim /// necessarily mean the twine is empty. 400198090Srdivacky bool isTriviallyEmpty() const { 401198090Srdivacky return isNullary(); 402198090Srdivacky } 403218893Sdim 404288943Sdim /// Return true if this twine can be dynamically accessed as a single 405288943Sdim /// StringRef value with getSingleStringRef(). 406202375Srdivacky bool isSingleStringRef() const { 407202375Srdivacky if (getRHSKind() != EmptyKind) return false; 408218893Sdim 409202375Srdivacky switch (getLHSKind()) { 410202375Srdivacky case EmptyKind: 411202375Srdivacky case CStringKind: 412202375Srdivacky case StdStringKind: 413202375Srdivacky case StringRefKind: 414288943Sdim case SmallStringKind: 415202375Srdivacky return true; 416202375Srdivacky default: 417202375Srdivacky return false; 418202375Srdivacky } 419202375Srdivacky } 420198090Srdivacky 421198090Srdivacky /// @} 422198090Srdivacky /// @name String Operations 423198090Srdivacky /// @{ 424198090Srdivacky 425198090Srdivacky Twine concat(const Twine &Suffix) const; 426198090Srdivacky 427198090Srdivacky /// @} 428198090Srdivacky /// @name Output & Conversion. 429198090Srdivacky /// @{ 430198090Srdivacky 431288943Sdim /// Return the twine contents as a std::string. 432198090Srdivacky std::string str() const; 433198090Srdivacky 434288943Sdim /// Append the concatenated string into the given SmallString or SmallVector. 435198090Srdivacky void toVector(SmallVectorImpl<char> &Out) const; 436198090Srdivacky 437288943Sdim /// This returns the twine as a single StringRef. This method is only valid 438288943Sdim /// if isSingleStringRef() is true. 439202375Srdivacky StringRef getSingleStringRef() const { 440202375Srdivacky assert(isSingleStringRef() &&"This cannot be had as a single stringref!"); 441202375Srdivacky switch (getLHSKind()) { 442234353Sdim default: llvm_unreachable("Out of sync with isSingleStringRef"); 443202375Srdivacky case EmptyKind: return StringRef(); 444226633Sdim case CStringKind: return StringRef(LHS.cString); 445226633Sdim case StdStringKind: return StringRef(*LHS.stdString); 446226633Sdim case StringRefKind: return *LHS.stringRef; 447288943Sdim case SmallStringKind: 448288943Sdim return StringRef(LHS.smallString->data(), LHS.smallString->size()); 449202375Srdivacky } 450202375Srdivacky } 451202375Srdivacky 452288943Sdim /// This returns the twine as a single StringRef if it can be 453202375Srdivacky /// represented as such. Otherwise the twine is written into the given 454202375Srdivacky /// SmallVector and a StringRef to the SmallVector's data is returned. 455288943Sdim StringRef toStringRef(SmallVectorImpl<char> &Out) const { 456288943Sdim if (isSingleStringRef()) 457288943Sdim return getSingleStringRef(); 458288943Sdim toVector(Out); 459288943Sdim return StringRef(Out.data(), Out.size()); 460288943Sdim } 461202375Srdivacky 462288943Sdim /// This returns the twine as a single null terminated StringRef if it 463288943Sdim /// can be represented as such. Otherwise the twine is written into the 464288943Sdim /// given SmallVector and a StringRef to the SmallVector's data is returned. 465218893Sdim /// 466218893Sdim /// The returned StringRef's size does not include the null terminator. 467218893Sdim StringRef toNullTerminatedStringRef(SmallVectorImpl<char> &Out) const; 468218893Sdim 469243830Sdim /// Write the concatenated string represented by this twine to the 470243830Sdim /// stream \p OS. 471198090Srdivacky void print(raw_ostream &OS) const; 472198090Srdivacky 473243830Sdim /// Dump the concatenated string represented by this twine to stderr. 474198090Srdivacky void dump() const; 475198090Srdivacky 476243830Sdim /// Write the representation of this twine to the stream \p OS. 477198090Srdivacky void printRepr(raw_ostream &OS) const; 478198090Srdivacky 479243830Sdim /// Dump the representation of this twine to stderr. 480198090Srdivacky void dumpRepr() const; 481198090Srdivacky 482198090Srdivacky /// @} 483198090Srdivacky }; 484198090Srdivacky 485198090Srdivacky /// @name Twine Inline Implementations 486198090Srdivacky /// @{ 487198090Srdivacky 488198090Srdivacky inline Twine Twine::concat(const Twine &Suffix) const { 489198090Srdivacky // Concatenation with null is null. 490198090Srdivacky if (isNull() || Suffix.isNull()) 491198090Srdivacky return Twine(NullKind); 492198090Srdivacky 493198090Srdivacky // Concatenation with empty yields the other side. 494198090Srdivacky if (isEmpty()) 495198090Srdivacky return Suffix; 496198090Srdivacky if (Suffix.isEmpty()) 497198090Srdivacky return *this; 498198090Srdivacky 499198090Srdivacky // Otherwise we need to create a new node, taking care to fold in unary 500198090Srdivacky // twines. 501226633Sdim Child NewLHS, NewRHS; 502226633Sdim NewLHS.twine = this; 503226633Sdim NewRHS.twine = &Suffix; 504198090Srdivacky NodeKind NewLHSKind = TwineKind, NewRHSKind = TwineKind; 505198090Srdivacky if (isUnary()) { 506198090Srdivacky NewLHS = LHS; 507198090Srdivacky NewLHSKind = getLHSKind(); 508198090Srdivacky } 509198090Srdivacky if (Suffix.isUnary()) { 510198090Srdivacky NewRHS = Suffix.LHS; 511198090Srdivacky NewRHSKind = Suffix.getLHSKind(); 512198090Srdivacky } 513198090Srdivacky 514198090Srdivacky return Twine(NewLHS, NewLHSKind, NewRHS, NewRHSKind); 515198090Srdivacky } 516198090Srdivacky 517198090Srdivacky inline Twine operator+(const Twine &LHS, const Twine &RHS) { 518198090Srdivacky return LHS.concat(RHS); 519198090Srdivacky } 520198090Srdivacky 521198090Srdivacky /// Additional overload to guarantee simplified codegen; this is equivalent to 522198090Srdivacky /// concat(). 523198090Srdivacky 524198090Srdivacky inline Twine operator+(const char *LHS, const StringRef &RHS) { 525198090Srdivacky return Twine(LHS, RHS); 526198090Srdivacky } 527198090Srdivacky 528198090Srdivacky /// Additional overload to guarantee simplified codegen; this is equivalent to 529198090Srdivacky /// concat(). 530198090Srdivacky 531198090Srdivacky inline Twine operator+(const StringRef &LHS, const char *RHS) { 532198090Srdivacky return Twine(LHS, RHS); 533198090Srdivacky } 534198090Srdivacky 535198090Srdivacky inline raw_ostream &operator<<(raw_ostream &OS, const Twine &RHS) { 536198090Srdivacky RHS.print(OS); 537198090Srdivacky return OS; 538198090Srdivacky } 539198090Srdivacky 540198090Srdivacky /// @} 541198090Srdivacky 542314564Sdim} // end namespace llvm 543314564Sdim 544314564Sdim#endif // LLVM_ADT_TWINE_H 545