Home | History | Annotate | Download | only in Support
      1 //===-- Twine.cpp - Fast Temporary String Concatenation -------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #include "llvm/ADT/Twine.h"
     11 #include "llvm/ADT/SmallString.h"
     12 #include "llvm/Support/Debug.h"
     13 #include "llvm/Support/FormatVariadic.h"
     14 #include "llvm/Support/raw_ostream.h"
     15 using namespace llvm;
     16 
     17 std::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 formatting
     23   // 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 
     32 void Twine::toVector(SmallVectorImpl<char> &Out) const {
     33   raw_svector_ostream OS(Out);
     34   print(OS);
     35 }
     36 
     37 StringRef 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     default:
     48       break;
     49     }
     50   }
     51   toVector(Out);
     52   Out.push_back(0);
     53   Out.pop_back();
     54   return StringRef(Out.data(), Out.size());
     55 }
     56 
     57 void Twine::printOneChild(raw_ostream &OS, Child Ptr,
     58                           NodeKind Kind) const {
     59   switch (Kind) {
     60   case Twine::NullKind: break;
     61   case Twine::EmptyKind: break;
     62   case Twine::TwineKind:
     63     Ptr.twine->print(OS);
     64     break;
     65   case Twine::CStringKind:
     66     OS << Ptr.cString;
     67     break;
     68   case Twine::StdStringKind:
     69     OS << *Ptr.stdString;
     70     break;
     71   case Twine::StringRefKind:
     72     OS << *Ptr.stringRef;
     73     break;
     74   case Twine::SmallStringKind:
     75     OS << *Ptr.smallString;
     76     break;
     77   case Twine::FormatvObjectKind:
     78     OS << *Ptr.formatvObject;
     79     break;
     80   case Twine::CharKind:
     81     OS << Ptr.character;
     82     break;
     83   case Twine::DecUIKind:
     84     OS << Ptr.decUI;
     85     break;
     86   case Twine::DecIKind:
     87     OS << Ptr.decI;
     88     break;
     89   case Twine::DecULKind:
     90     OS << *Ptr.decUL;
     91     break;
     92   case Twine::DecLKind:
     93     OS << *Ptr.decL;
     94     break;
     95   case Twine::DecULLKind:
     96     OS << *Ptr.decULL;
     97     break;
     98   case Twine::DecLLKind:
     99     OS << *Ptr.decLL;
    100     break;
    101   case Twine::UHexKind:
    102     OS.write_hex(*Ptr.uHex);
    103     break;
    104   }
    105 }
    106 
    107 void Twine::printOneChildRepr(raw_ostream &OS, Child Ptr,
    108                               NodeKind Kind) const {
    109   switch (Kind) {
    110   case Twine::NullKind:
    111     OS << "null"; break;
    112   case Twine::EmptyKind:
    113     OS << "empty"; break;
    114   case Twine::TwineKind:
    115     OS << "rope:";
    116     Ptr.twine->printRepr(OS);
    117     break;
    118   case Twine::CStringKind:
    119     OS << "cstring:\""
    120        << Ptr.cString << "\"";
    121     break;
    122   case Twine::StdStringKind:
    123     OS << "std::string:\""
    124        << Ptr.stdString << "\"";
    125     break;
    126   case Twine::StringRefKind:
    127     OS << "stringref:\""
    128        << Ptr.stringRef << "\"";
    129     break;
    130   case Twine::SmallStringKind:
    131     OS << "smallstring:\"" << *Ptr.smallString << "\"";
    132     break;
    133   case Twine::FormatvObjectKind:
    134     OS << "formatv:\"" << *Ptr.formatvObject << "\"";
    135     break;
    136   case Twine::CharKind:
    137     OS << "char:\"" << Ptr.character << "\"";
    138     break;
    139   case Twine::DecUIKind:
    140     OS << "decUI:\"" << Ptr.decUI << "\"";
    141     break;
    142   case Twine::DecIKind:
    143     OS << "decI:\"" << Ptr.decI << "\"";
    144     break;
    145   case Twine::DecULKind:
    146     OS << "decUL:\"" << *Ptr.decUL << "\"";
    147     break;
    148   case Twine::DecLKind:
    149     OS << "decL:\"" << *Ptr.decL << "\"";
    150     break;
    151   case Twine::DecULLKind:
    152     OS << "decULL:\"" << *Ptr.decULL << "\"";
    153     break;
    154   case Twine::DecLLKind:
    155     OS << "decLL:\"" << *Ptr.decLL << "\"";
    156     break;
    157   case Twine::UHexKind:
    158     OS << "uhex:\"" << Ptr.uHex << "\"";
    159     break;
    160   }
    161 }
    162 
    163 void Twine::print(raw_ostream &OS) const {
    164   printOneChild(OS, LHS, getLHSKind());
    165   printOneChild(OS, RHS, getRHSKind());
    166 }
    167 
    168 void Twine::printRepr(raw_ostream &OS) const {
    169   OS << "(Twine ";
    170   printOneChildRepr(OS, LHS, getLHSKind());
    171   OS << " ";
    172   printOneChildRepr(OS, RHS, getRHSKind());
    173   OS << ")";
    174 }
    175 
    176 LLVM_DUMP_METHOD void Twine::dump() const {
    177   print(dbgs());
    178 }
    179 
    180 void Twine::dumpRepr() const {
    181   printRepr(dbgs());
    182 }
    183