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