12538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar//===-- Twine.h - Fast Temporary String Concatenation -----------*- C++ -*-===// 22538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar// 32538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar// The LLVM Compiler Infrastructure 42538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar// 52538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar// This file is distributed under the University of Illinois Open Source 62538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar// License. See LICENSE.TXT for details. 72538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar// 82538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar//===----------------------------------------------------------------------===// 92538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 102538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar#ifndef LLVM_ADT_TWINE_H 112538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar#define LLVM_ADT_TWINE_H 122538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 132538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar#include "llvm/ADT/StringRef.h" 141f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/DataTypes.h" 1550bee42b54cd9aec5f49566307df2b0cf23afcf6Craig Topper#include "llvm/Support/ErrorHandling.h" 162538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar#include <cassert> 172538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar#include <string> 182538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 192538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbarnamespace llvm { 202538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar template <typename T> 212538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar class SmallVectorImpl; 222538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar class StringRef; 232538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar class raw_ostream; 242538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 252538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// Twine - A lightweight data structure for efficiently representing the 262538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// concatenation of temporary values as strings. 272538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// 282538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// A Twine is a kind of rope, it represents a concatenated string using a 292538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// binary-tree, where the string is the preorder of the nodes. Since the 302538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// Twine can be efficiently rendered into a buffer when its result is used, 312538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// it avoids the cost of generating temporary values for intermediate string 322538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// results -- particularly in cases when the Twine result is never 332538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// required. By explicitly tracking the type of leaf nodes, we can also avoid 342538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// the creation of temporary strings for conversions operations (such as 352538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// appending an integer to a string). 362538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// 372538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// A Twine is not intended for use directly and should not be stored, its 382538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// implementation relies on the ability to store pointers to temporary stack 392538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// objects which may be deallocated at the end of a statement. Twines should 402538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// only be used accepted as const references in arguments, when an API wishes 412538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// to accept possibly-concatenated strings. 422538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// 432538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// Twines support a special 'null' value, which always concatenates to form 442538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// itself, and renders as an empty string. This can be returned from APIs to 452538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// effectively nullify any concatenations performed on the result. 46326990f1eb7ff005adabe46a1f982eff8835813eMichael J. Spencer /// 472d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko /// \b Implementation 482538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// 492538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// Given the nature of a Twine, it is not possible for the Twine's 502538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// concatenation method to construct interior nodes; the result must be 512538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// represented inside the returned value. For this reason a Twine object 522538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// actually holds two values, the left- and right-hand sides of a 532538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// concatenation. We also have nullary Twine objects, which are effectively 542538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// sentinel values that represent empty strings. 552538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// 562538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// Thus, a Twine can effectively have zero, one, or two children. The \see 572538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// isNullary(), \see isUnary(), and \see isBinary() predicates exist for 582538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// testing the number of children. 592538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// 602538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// We maintain a number of invariants on Twine objects (FIXME: Why): 612538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// - Nullary twines are always represented with their Kind on the left-hand 622538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// side, and the Empty kind on the right-hand side. 632538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// - Unary twines are always represented with the value on the left-hand 642538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// side, and the Empty kind on the right-hand side. 652538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// - If a Twine has another Twine as a child, that child should always be 662538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// binary (otherwise it could have been folded into the parent). 672538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// 682538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// These invariants are check by \see isValid(). 692538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// 702d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko /// \b Efficiency Considerations 712538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// 722538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// The Twine is designed to yield efficient and small code for common 732538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// situations. For this reason, the concat() method is inlined so that 742538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// concatenations of leaf nodes can be optimized into stores directly into a 752538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// single stack allocated object. 762538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// 772538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// In practice, not all compilers can be trusted to optimize concat() fully, 782538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// so we provide two additional methods (and accompanying operator+ 792538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// overloads) to guarantee that particularly important cases (cstring plus 802538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// StringRef) codegen as desired. 812538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar class Twine { 822538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// NodeKind - Represent the type of an argument. 832538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar enum NodeKind { 842538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// An empty string; the result of concatenating anything with it is also 852538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// empty. 862538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar NullKind, 872538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 882538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// The empty string. 892538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar EmptyKind, 902538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 91763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbar /// A pointer to a Twine instance. 92763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbar TwineKind, 93763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbar 942538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// A pointer to a C string instance. 952538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar CStringKind, 962538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 972538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// A pointer to an std::string instance. 982538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar StdStringKind, 992538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 1002538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// A pointer to a StringRef instance. 1012538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar StringRefKind, 1022538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 1033f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner /// A char value reinterpreted as a pointer, to render as a character. 1043f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner CharKind, 1053f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner 106326990f1eb7ff005adabe46a1f982eff8835813eMichael J. Spencer /// An unsigned int value reinterpreted as a pointer, to render as an 107ea03e10facd07f0b239dcc3a5e31346686acae3cChris Lattner /// unsigned decimal integer. 1082d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar DecUIKind, 109763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbar 110ea03e10facd07f0b239dcc3a5e31346686acae3cChris Lattner /// An int value reinterpreted as a pointer, to render as a signed 111ea03e10facd07f0b239dcc3a5e31346686acae3cChris Lattner /// decimal integer. 1122d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar DecIKind, 1130165a2ca897598bb95baec031362921565e24f2bDaniel Dunbar 1142d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar /// A pointer to an unsigned long value, to render as an unsigned decimal 115763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbar /// integer. 1162d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar DecULKind, 117763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbar 1182d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar /// A pointer to a long value, to render as a signed decimal integer. 1192d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar DecLKind, 1202d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar 1212d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar /// A pointer to an unsigned long long value, to render as an unsigned 1222d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar /// decimal integer. 1232d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar DecULLKind, 1242d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar 1252d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar /// A pointer to a long long value, to render as a signed decimal integer. 1262d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar DecLLKind, 1270165a2ca897598bb95baec031362921565e24f2bDaniel Dunbar 1280165a2ca897598bb95baec031362921565e24f2bDaniel Dunbar /// A pointer to a uint64_t value, to render as an unsigned hexadecimal 1290165a2ca897598bb95baec031362921565e24f2bDaniel Dunbar /// integer. 1300165a2ca897598bb95baec031362921565e24f2bDaniel Dunbar UHexKind 1312538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar }; 1322538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 1333f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner union Child 1343f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner { 1353f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner const Twine *twine; 1363f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner const char *cString; 1373f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner const std::string *stdString; 1383f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner const StringRef *stringRef; 1393f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner char character; 1403f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner unsigned int decUI; 1413f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner int decI; 1423f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner const unsigned long *decUL; 1433f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner const long *decL; 1443f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner const unsigned long long *decULL; 1453f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner const long long *decLL; 1463f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner const uint64_t *uHex; 1473f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner }; 1483f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner 1492538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar private: 1502538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// LHS - The prefix in the concatenation, which may be uninitialized for 1512538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// Null or Empty kinds. 1523f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner Child LHS; 1532538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// RHS - The suffix in the concatenation, which may be uninitialized for 1542538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// Null or Empty kinds. 1553f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner Child RHS; 1563f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner // enums stored as unsigned chars to save on space while some compilers 1573f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner // don't support specifying the backing type for an enum 1582538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// LHSKind - The NodeKind of the left hand side, \see getLHSKind(). 159b80077aae9fe51af78e6e25e26d09bf8efcd8244Daniel Dunbar unsigned char LHSKind; 1602538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// RHSKind - The NodeKind of the left hand side, \see getLHSKind(). 161b80077aae9fe51af78e6e25e26d09bf8efcd8244Daniel Dunbar unsigned char RHSKind; 1622538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 1632538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar private: 1642538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// Construct a nullary twine; the kind must be NullKind or EmptyKind. 1652538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar explicit Twine(NodeKind Kind) 1662538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar : LHSKind(Kind), RHSKind(EmptyKind) { 1672538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar assert(isNullary() && "Invalid kind!"); 1682538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar } 1692538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 1702538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// Construct a binary twine. 1712538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar explicit Twine(const Twine &_LHS, const Twine &_RHS) 1723f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner : LHSKind(TwineKind), RHSKind(TwineKind) { 1733f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner LHS.twine = &_LHS; 1743f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner RHS.twine = &_RHS; 1752538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar assert(isValid() && "Invalid twine!"); 1762538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar } 1772538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 1782538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// Construct a twine from explicit values. 1793f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner explicit Twine(Child _LHS, NodeKind _LHSKind, 1803f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner Child _RHS, NodeKind _RHSKind) 1812538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar : LHS(_LHS), RHS(_RHS), LHSKind(_LHSKind), RHSKind(_RHSKind) { 1822538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar assert(isValid() && "Invalid twine!"); 1832538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar } 1842538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 185cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// Since the intended use of twines is as temporary objects, assignments 186cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// when concatenating might cause undefined behavior or stack corruptions 187cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Twine &operator=(const Twine &Other) LLVM_DELETED_FUNCTION; 188cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 1892538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// isNull - Check for the null twine. 1902538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar bool isNull() const { 1912538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar return getLHSKind() == NullKind; 1922538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar } 1932538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 1942538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// isEmpty - Check for the empty twine. 1952538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar bool isEmpty() const { 1962538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar return getLHSKind() == EmptyKind; 1972538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar } 1982538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 1992538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// isNullary - Check if this is a nullary twine (null or empty). 2002538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar bool isNullary() const { 2012538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar return isNull() || isEmpty(); 2022538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar } 2032538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 2042538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// isUnary - Check if this is a unary twine. 2052538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar bool isUnary() const { 2062538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar return getRHSKind() == EmptyKind && !isNullary(); 2072538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar } 2082538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 2092538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// isBinary - Check if this is a binary twine. 2102538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar bool isBinary() const { 2112538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar return getLHSKind() != NullKind && getRHSKind() != EmptyKind; 2122538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar } 2132538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 2142538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// isValid - Check if this is a valid twine (satisfying the invariants on 2152538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// order and number of arguments). 2162538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar bool isValid() const { 2172538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar // Nullary twines always have Empty on the RHS. 2182538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar if (isNullary() && getRHSKind() != EmptyKind) 2192538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar return false; 2202538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 2212538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar // Null should never appear on the RHS. 2222538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar if (getRHSKind() == NullKind) 2232538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar return false; 2242538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 2252538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar // The RHS cannot be non-empty if the LHS is empty. 2262538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar if (getRHSKind() != EmptyKind && getLHSKind() == EmptyKind) 2272538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar return false; 2282538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 2292538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar // A twine child should always be binary. 2302538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar if (getLHSKind() == TwineKind && 2313f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner !LHS.twine->isBinary()) 2322538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar return false; 2332538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar if (getRHSKind() == TwineKind && 2343f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner !RHS.twine->isBinary()) 2352538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar return false; 2362538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 2372538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar return true; 2382538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar } 2392538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 2402538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// getLHSKind - Get the NodeKind of the left-hand side. 241b80077aae9fe51af78e6e25e26d09bf8efcd8244Daniel Dunbar NodeKind getLHSKind() const { return (NodeKind) LHSKind; } 2422538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 2438bb3b098b98cd62f074bb488d8294498ae8121e3Eli Bendersky /// getRHSKind - Get the NodeKind of the right-hand side. 244b80077aae9fe51af78e6e25e26d09bf8efcd8244Daniel Dunbar NodeKind getRHSKind() const { return (NodeKind) RHSKind; } 2452538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 2462538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// printOneChild - Print one child from a twine. 2473f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner void printOneChild(raw_ostream &OS, Child Ptr, NodeKind Kind) const; 2482538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 2492538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// printOneChildRepr - Print the representation of one child from a twine. 2503f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner void printOneChildRepr(raw_ostream &OS, Child Ptr, 2512538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar NodeKind Kind) const; 2522538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 2532538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar public: 2542538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// @name Constructors 2552538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// @{ 2562538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 2572538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// Construct from an empty string. 2582538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /*implicit*/ Twine() : LHSKind(EmptyKind), RHSKind(EmptyKind) { 2592538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar assert(isValid() && "Invalid twine!"); 2602538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar } 2612538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 2622538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// Construct from a C string. 2632538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// 2642538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// We take care here to optimize "" into the empty twine -- this will be 2652538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// optimized out for string constants. This allows Twine arguments have 2662538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// default "" values, without introducing unnecessary string constants. 2672538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /*implicit*/ Twine(const char *Str) 2682538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar : RHSKind(EmptyKind) { 2692538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar if (Str[0] != '\0') { 2703f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner LHS.cString = Str; 2712538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar LHSKind = CStringKind; 2722538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar } else 2732538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar LHSKind = EmptyKind; 2742538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 2752538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar assert(isValid() && "Invalid twine!"); 2762538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar } 2772538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 2782538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// Construct from an std::string. 2792538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /*implicit*/ Twine(const std::string &Str) 2803f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner : LHSKind(StdStringKind), RHSKind(EmptyKind) { 2813f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner LHS.stdString = &Str; 2822538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar assert(isValid() && "Invalid twine!"); 2832538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar } 2842538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 2852538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// Construct from a StringRef. 2862538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /*implicit*/ Twine(const StringRef &Str) 2873f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner : LHSKind(StringRefKind), RHSKind(EmptyKind) { 2883f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner LHS.stringRef = &Str; 2892538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar assert(isValid() && "Invalid twine!"); 2902538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar } 2912538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 2923f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner /// Construct from a char. 2933f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner explicit Twine(char Val) 2943f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner : LHSKind(CharKind), RHSKind(EmptyKind) { 2953f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner LHS.character = Val; 2963f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner } 2973f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner 2983f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner /// Construct from a signed char. 2993f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner explicit Twine(signed char Val) 3003f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner : LHSKind(CharKind), RHSKind(EmptyKind) { 3013f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner LHS.character = static_cast<char>(Val); 3023f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner } 3033f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner 3043f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner /// Construct from an unsigned char. 3053f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner explicit Twine(unsigned char Val) 3063f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner : LHSKind(CharKind), RHSKind(EmptyKind) { 3073f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner LHS.character = static_cast<char>(Val); 3083f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner } 3093f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner 3102d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko /// Construct a twine to print \p Val as an unsigned decimal integer. 311326990f1eb7ff005adabe46a1f982eff8835813eMichael J. Spencer explicit Twine(unsigned Val) 3123f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner : LHSKind(DecUIKind), RHSKind(EmptyKind) { 3133f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner LHS.decUI = Val; 3142d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar } 3152d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar 3162d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko /// Construct a twine to print \p Val as a signed decimal integer. 317326990f1eb7ff005adabe46a1f982eff8835813eMichael J. Spencer explicit Twine(int Val) 3183f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner : LHSKind(DecIKind), RHSKind(EmptyKind) { 3193f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner LHS.decI = Val; 3202d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar } 3212d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar 3222d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko /// Construct a twine to print \p Val as an unsigned decimal integer. 323326990f1eb7ff005adabe46a1f982eff8835813eMichael J. Spencer explicit Twine(const unsigned long &Val) 3243f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner : LHSKind(DecULKind), RHSKind(EmptyKind) { 3253f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner LHS.decUL = &Val; 3260165a2ca897598bb95baec031362921565e24f2bDaniel Dunbar } 3270165a2ca897598bb95baec031362921565e24f2bDaniel Dunbar 3282d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko /// Construct a twine to print \p Val as a signed decimal integer. 329326990f1eb7ff005adabe46a1f982eff8835813eMichael J. Spencer explicit Twine(const long &Val) 3303f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner : LHSKind(DecLKind), RHSKind(EmptyKind) { 3313f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner LHS.decL = &Val; 3320165a2ca897598bb95baec031362921565e24f2bDaniel Dunbar } 3330165a2ca897598bb95baec031362921565e24f2bDaniel Dunbar 3342d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko /// Construct a twine to print \p Val as an unsigned decimal integer. 335326990f1eb7ff005adabe46a1f982eff8835813eMichael J. Spencer explicit Twine(const unsigned long long &Val) 3363f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner : LHSKind(DecULLKind), RHSKind(EmptyKind) { 3373f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner LHS.decULL = &Val; 3380165a2ca897598bb95baec031362921565e24f2bDaniel Dunbar } 3390165a2ca897598bb95baec031362921565e24f2bDaniel Dunbar 3402d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko /// Construct a twine to print \p Val as a signed decimal integer. 341326990f1eb7ff005adabe46a1f982eff8835813eMichael J. Spencer explicit Twine(const long long &Val) 3423f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner : LHSKind(DecLLKind), RHSKind(EmptyKind) { 3433f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner LHS.decLL = &Val; 3440165a2ca897598bb95baec031362921565e24f2bDaniel Dunbar } 3450165a2ca897598bb95baec031362921565e24f2bDaniel Dunbar 3462538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar // FIXME: Unfortunately, to make sure this is as efficient as possible we 3472538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar // need extra binary constructors from particular types. We can't rely on 3482538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar // the compiler to be smart enough to fold operator+()/concat() down to the 3492538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar // right thing. Yet. 3502538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 3512538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// Construct as the concatenation of a C string and a StringRef. 3522538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /*implicit*/ Twine(const char *_LHS, const StringRef &_RHS) 3533f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner : LHSKind(CStringKind), RHSKind(StringRefKind) { 3543f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner LHS.cString = _LHS; 3553f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner RHS.stringRef = &_RHS; 3562538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar assert(isValid() && "Invalid twine!"); 3572538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar } 3582538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 3592538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// Construct as the concatenation of a StringRef and a C string. 3602538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /*implicit*/ Twine(const StringRef &_LHS, const char *_RHS) 3613f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner : LHSKind(StringRefKind), RHSKind(CStringKind) { 3623f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner LHS.stringRef = &_LHS; 3633f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner RHS.cString = _RHS; 3642538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar assert(isValid() && "Invalid twine!"); 3652538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar } 3662538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 367763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbar /// Create a 'null' string, which is an empty string that always 368763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbar /// concatenates to form another empty string. 369763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbar static Twine createNull() { 370763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbar return Twine(NullKind); 371763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbar } 372763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbar 373763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbar /// @} 374763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbar /// @name Numeric Conversions 375763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbar /// @{ 376763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbar 3772d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko // Construct a twine to print \p Val as an unsigned hexadecimal integer. 378763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbar static Twine utohexstr(const uint64_t &Val) { 3793f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner Child LHS, RHS; 3803f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner LHS.uHex = &Val; 381dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines RHS.twine = nullptr; 3823f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner return Twine(LHS, UHexKind, RHS, EmptyKind); 383763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbar } 384763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbar 3852538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// @} 3865149932068f535e1ff13b91c9669f55718c60a07Daniel Dunbar /// @name Predicate Operations 3875149932068f535e1ff13b91c9669f55718c60a07Daniel Dunbar /// @{ 3885149932068f535e1ff13b91c9669f55718c60a07Daniel Dunbar 3895149932068f535e1ff13b91c9669f55718c60a07Daniel Dunbar /// isTriviallyEmpty - Check if this twine is trivially empty; a false 3905149932068f535e1ff13b91c9669f55718c60a07Daniel Dunbar /// return value does not necessarily mean the twine is empty. 3915149932068f535e1ff13b91c9669f55718c60a07Daniel Dunbar bool isTriviallyEmpty() const { 3925149932068f535e1ff13b91c9669f55718c60a07Daniel Dunbar return isNullary(); 3935149932068f535e1ff13b91c9669f55718c60a07Daniel Dunbar } 394326990f1eb7ff005adabe46a1f982eff8835813eMichael J. Spencer 395bf86e5df180139310bf2f0d71bef58e208dce31dChris Lattner /// isSingleStringRef - Return true if this twine can be dynamically 396bf86e5df180139310bf2f0d71bef58e208dce31dChris Lattner /// accessed as a single StringRef value with getSingleStringRef(). 397bf86e5df180139310bf2f0d71bef58e208dce31dChris Lattner bool isSingleStringRef() const { 398bf86e5df180139310bf2f0d71bef58e208dce31dChris Lattner if (getRHSKind() != EmptyKind) return false; 399326990f1eb7ff005adabe46a1f982eff8835813eMichael J. Spencer 400bf86e5df180139310bf2f0d71bef58e208dce31dChris Lattner switch (getLHSKind()) { 401bf86e5df180139310bf2f0d71bef58e208dce31dChris Lattner case EmptyKind: 402bf86e5df180139310bf2f0d71bef58e208dce31dChris Lattner case CStringKind: 403bf86e5df180139310bf2f0d71bef58e208dce31dChris Lattner case StdStringKind: 404bf86e5df180139310bf2f0d71bef58e208dce31dChris Lattner case StringRefKind: 405bf86e5df180139310bf2f0d71bef58e208dce31dChris Lattner return true; 406bf86e5df180139310bf2f0d71bef58e208dce31dChris Lattner default: 407bf86e5df180139310bf2f0d71bef58e208dce31dChris Lattner return false; 408bf86e5df180139310bf2f0d71bef58e208dce31dChris Lattner } 409bf86e5df180139310bf2f0d71bef58e208dce31dChris Lattner } 4105149932068f535e1ff13b91c9669f55718c60a07Daniel Dunbar 4115149932068f535e1ff13b91c9669f55718c60a07Daniel Dunbar /// @} 4122538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// @name String Operations 4132538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// @{ 4142538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 4152538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar Twine concat(const Twine &Suffix) const; 4162538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 4172538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// @} 4182538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// @name Output & Conversion. 4192538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// @{ 4202538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 4212538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// str - Return the twine contents as a std::string. 4222538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar std::string str() const; 4232538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 4242538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// toVector - Write the concatenated string into the given SmallString or 4252538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// SmallVector. 4262538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar void toVector(SmallVectorImpl<char> &Out) const; 4272538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 428bf86e5df180139310bf2f0d71bef58e208dce31dChris Lattner /// getSingleStringRef - This returns the twine as a single StringRef. This 429bf86e5df180139310bf2f0d71bef58e208dce31dChris Lattner /// method is only valid if isSingleStringRef() is true. 430bf86e5df180139310bf2f0d71bef58e208dce31dChris Lattner StringRef getSingleStringRef() const { 431bf86e5df180139310bf2f0d71bef58e208dce31dChris Lattner assert(isSingleStringRef() &&"This cannot be had as a single stringref!"); 432bf86e5df180139310bf2f0d71bef58e208dce31dChris Lattner switch (getLHSKind()) { 43350bee42b54cd9aec5f49566307df2b0cf23afcf6Craig Topper default: llvm_unreachable("Out of sync with isSingleStringRef"); 434bf86e5df180139310bf2f0d71bef58e208dce31dChris Lattner case EmptyKind: return StringRef(); 4353f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner case CStringKind: return StringRef(LHS.cString); 4363f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner case StdStringKind: return StringRef(*LHS.stdString); 4373f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner case StringRefKind: return *LHS.stringRef; 438bf86e5df180139310bf2f0d71bef58e208dce31dChris Lattner } 439bf86e5df180139310bf2f0d71bef58e208dce31dChris Lattner } 440b357e06f672996400343d38b08014a5b6a7d5b2dBenjamin Kramer 441b357e06f672996400343d38b08014a5b6a7d5b2dBenjamin Kramer /// toStringRef - This returns the twine as a single StringRef if it can be 442b357e06f672996400343d38b08014a5b6a7d5b2dBenjamin Kramer /// represented as such. Otherwise the twine is written into the given 443b357e06f672996400343d38b08014a5b6a7d5b2dBenjamin Kramer /// SmallVector and a StringRef to the SmallVector's data is returned. 444b357e06f672996400343d38b08014a5b6a7d5b2dBenjamin Kramer StringRef toStringRef(SmallVectorImpl<char> &Out) const; 445b357e06f672996400343d38b08014a5b6a7d5b2dBenjamin Kramer 4467dc7ac3cb20b7ef8e6febe0ac3bc430230f29893Michael J. Spencer /// toNullTerminatedStringRef - This returns the twine as a single null 4477dc7ac3cb20b7ef8e6febe0ac3bc430230f29893Michael J. Spencer /// terminated StringRef if it can be represented as such. Otherwise the 4487dc7ac3cb20b7ef8e6febe0ac3bc430230f29893Michael J. Spencer /// twine is written into the given SmallVector and a StringRef to the 4497dc7ac3cb20b7ef8e6febe0ac3bc430230f29893Michael J. Spencer /// SmallVector's data is returned. 4507dc7ac3cb20b7ef8e6febe0ac3bc430230f29893Michael J. Spencer /// 4517dc7ac3cb20b7ef8e6febe0ac3bc430230f29893Michael J. Spencer /// The returned StringRef's size does not include the null terminator. 4527dc7ac3cb20b7ef8e6febe0ac3bc430230f29893Michael J. Spencer StringRef toNullTerminatedStringRef(SmallVectorImpl<char> &Out) const; 4537dc7ac3cb20b7ef8e6febe0ac3bc430230f29893Michael J. Spencer 4542d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko /// Write the concatenated string represented by this twine to the 4552d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko /// stream \p OS. 4562538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar void print(raw_ostream &OS) const; 4572538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 4582d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko /// Dump the concatenated string represented by this twine to stderr. 4592538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar void dump() const; 4602538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 4612d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko /// Write the representation of this twine to the stream \p OS. 4622538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar void printRepr(raw_ostream &OS) const; 4632538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 4642d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko /// Dump the representation of this twine to stderr. 4652538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar void dumpRepr() const; 4662538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 4672538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// @} 4682538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar }; 4692538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 4702538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// @name Twine Inline Implementations 4712538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// @{ 4722538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 4732538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar inline Twine Twine::concat(const Twine &Suffix) const { 4742538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar // Concatenation with null is null. 4752538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar if (isNull() || Suffix.isNull()) 4762538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar return Twine(NullKind); 4772538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 4782538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar // Concatenation with empty yields the other side. 4792538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar if (isEmpty()) 4802538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar return Suffix; 4812538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar if (Suffix.isEmpty()) 4822538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar return *this; 4832538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 4842538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar // Otherwise we need to create a new node, taking care to fold in unary 4852538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar // twines. 4863f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner Child NewLHS, NewRHS; 4873f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner NewLHS.twine = this; 4883f25ee080ca7c92ff735df29c78e7cfbd62c8cb6Chris Lattner NewRHS.twine = &Suffix; 4892538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar NodeKind NewLHSKind = TwineKind, NewRHSKind = TwineKind; 4902538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar if (isUnary()) { 4912538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar NewLHS = LHS; 4922538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar NewLHSKind = getLHSKind(); 4932538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar } 4942538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar if (Suffix.isUnary()) { 4952538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar NewRHS = Suffix.LHS; 4962538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar NewRHSKind = Suffix.getLHSKind(); 4972538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar } 4982538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 4992538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar return Twine(NewLHS, NewLHSKind, NewRHS, NewRHSKind); 5002538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar } 5012538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 5022538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar inline Twine operator+(const Twine &LHS, const Twine &RHS) { 5032538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar return LHS.concat(RHS); 5042538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar } 5052538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 5062538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// Additional overload to guarantee simplified codegen; this is equivalent to 5072538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// concat(). 5082538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 5092538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar inline Twine operator+(const char *LHS, const StringRef &RHS) { 5102538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar return Twine(LHS, RHS); 5112538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar } 5122538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 5132538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// Additional overload to guarantee simplified codegen; this is equivalent to 5142538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// concat(). 5152538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 5162538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar inline Twine operator+(const StringRef &LHS, const char *RHS) { 5172538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar return Twine(LHS, RHS); 5182538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar } 5192538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 5202538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar inline raw_ostream &operator<<(raw_ostream &OS, const Twine &RHS) { 5212538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar RHS.print(OS); 5222538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar return OS; 5232538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar } 5242538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 5252538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar /// @} 5262538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar} 5272538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar 5282538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar#endif 529