182 lines · cpp
1//===-- Twine.cpp - Fast Temporary String Concatenation -------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/ADT/Twine.h"10#include "llvm/ADT/SmallString.h"11#include "llvm/Config/llvm-config.h"12#include "llvm/Support/Debug.h"13#include "llvm/Support/FormatVariadic.h"14#include "llvm/Support/raw_ostream.h"15using namespace llvm;16 17std::string Twine::str() const {18 // If we're storing only a std::string, just return it.19 if (LHSKind == StdStringKind && RHSKind == EmptyKind)20 return *LHS.stdString;21 22 // If we're storing a formatv_object, we can avoid an extra copy by formatting23 // it immediately and returning the result.24 if (LHSKind == FormatvObjectKind && RHSKind == EmptyKind)25 return LHS.formatvObject->str();26 27 // Otherwise, flatten and copy the contents first.28 SmallString<256> Vec;29 return toStringRef(Vec).str();30}31 32void Twine::toVector(SmallVectorImpl<char> &Out) const {33 raw_svector_ostream OS(Out);34 print(OS);35}36 37StringRef Twine::toNullTerminatedStringRef(SmallVectorImpl<char> &Out) const {38 if (isUnary()) {39 switch (getLHSKind()) {40 case CStringKind:41 // Already null terminated, yay!42 return StringRef(LHS.cString);43 case StdStringKind: {44 const std::string *str = LHS.stdString;45 return StringRef(str->c_str(), str->size());46 }47 case StringLiteralKind:48 return StringRef(LHS.ptrAndLength.ptr, LHS.ptrAndLength.length);49 default:50 break;51 }52 }53 toVector(Out);54 Out.push_back(0);55 Out.pop_back();56 return StringRef(Out.data(), Out.size());57}58 59void Twine::printOneChild(raw_ostream &OS, Child Ptr, NodeKind Kind) const {60 switch (Kind) {61 case Twine::NullKind:62 break;63 case Twine::EmptyKind:64 break;65 case Twine::TwineKind:66 Ptr.twine->print(OS);67 break;68 case Twine::CStringKind:69 OS << Ptr.cString;70 break;71 case Twine::StdStringKind:72 OS << *Ptr.stdString;73 break;74 case Twine::PtrAndLengthKind:75 case Twine::StringLiteralKind:76 OS << StringRef(Ptr.ptrAndLength.ptr, Ptr.ptrAndLength.length);77 break;78 case Twine::FormatvObjectKind:79 OS << *Ptr.formatvObject;80 break;81 case Twine::CharKind:82 OS << Ptr.character;83 break;84 case Twine::DecUIKind:85 OS << Ptr.decUI;86 break;87 case Twine::DecIKind:88 OS << Ptr.decI;89 break;90 case Twine::DecULKind:91 OS << Ptr.decUL;92 break;93 case Twine::DecLKind:94 OS << Ptr.decL;95 break;96 case Twine::DecULLKind:97 OS << Ptr.decULL;98 break;99 case Twine::DecLLKind:100 OS << Ptr.decLL;101 break;102 case Twine::UHexKind:103 OS.write_hex(Ptr.uHex);104 break;105 }106}107 108void Twine::printOneChildRepr(raw_ostream &OS, Child Ptr, NodeKind Kind) const {109 switch (Kind) {110 case Twine::NullKind:111 OS << "null";112 break;113 case Twine::EmptyKind:114 OS << "empty";115 break;116 case Twine::TwineKind:117 OS << "rope:";118 Ptr.twine->printRepr(OS);119 break;120 case Twine::CStringKind:121 OS << "cstring:\"" << Ptr.cString << "\"";122 break;123 case Twine::StdStringKind:124 OS << "std::string:\"" << Ptr.stdString << "\"";125 break;126 case Twine::PtrAndLengthKind:127 OS << "ptrAndLength:\""128 << StringRef(Ptr.ptrAndLength.ptr, Ptr.ptrAndLength.length) << "\"";129 break;130 case Twine::StringLiteralKind:131 OS << "constexprPtrAndLength:\""132 << StringRef(Ptr.ptrAndLength.ptr, Ptr.ptrAndLength.length) << "\"";133 break;134 case Twine::FormatvObjectKind:135 OS << "formatv:\"" << *Ptr.formatvObject << "\"";136 break;137 case Twine::CharKind:138 OS << "char:\"" << Ptr.character << "\"";139 break;140 case Twine::DecUIKind:141 OS << "decUI:\"" << Ptr.decUI << "\"";142 break;143 case Twine::DecIKind:144 OS << "decI:\"" << Ptr.decI << "\"";145 break;146 case Twine::DecULKind:147 OS << "decUL:\"" << Ptr.decUL << "\"";148 break;149 case Twine::DecLKind:150 OS << "decL:\"" << Ptr.decL << "\"";151 break;152 case Twine::DecULLKind:153 OS << "decULL:\"" << Ptr.decULL << "\"";154 break;155 case Twine::DecLLKind:156 OS << "decLL:\"" << Ptr.decLL << "\"";157 break;158 case Twine::UHexKind:159 OS << "uhex:\"" << Ptr.uHex << "\"";160 break;161 }162}163 164void Twine::print(raw_ostream &OS) const {165 printOneChild(OS, LHS, getLHSKind());166 printOneChild(OS, RHS, getRHSKind());167}168 169void Twine::printRepr(raw_ostream &OS) const {170 OS << "(Twine ";171 printOneChildRepr(OS, LHS, getLHSKind());172 OS << " ";173 printOneChildRepr(OS, RHS, getRHSKind());174 OS << ")";175}176 177#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)178LLVM_DUMP_METHOD void Twine::dump() const { print(dbgs()); }179 180LLVM_DUMP_METHOD void Twine::dumpRepr() const { printRepr(dbgs()); }181#endif182