mirror of
https://github.com/RPCS3/llvm.git
synced 2025-05-17 10:55:58 +00:00

There's a lot of misuse of Twine scattered around LLVM. This ranges in severity from benign (returning a Twine from a function by value that is just a string literal) to pretty sketchy (storing a Twine by value in a class). While there are some uses for copying Twines, most of the very compelling ones are confined to the Twine class implementation itself, and other uses are either dubious or easily worked around. This patch makes Twine's copy constructor private, and fixes up all callsites. Differential Revision: https://reviews.llvm.org/D38767 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@315530 91177308-0d34-0410-b5e6-96231b3b80d8
183 lines
4.5 KiB
C++
183 lines
4.5 KiB
C++
//===-- Twine.cpp - Fast Temporary String Concatenation -------------------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/ADT/Twine.h"
|
|
#include "llvm/ADT/SmallString.h"
|
|
#include "llvm/Support/Debug.h"
|
|
#include "llvm/Support/FormatVariadic.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
using namespace llvm;
|
|
|
|
std::string Twine::str() const {
|
|
// If we're storing only a std::string, just return it.
|
|
if (LHSKind == StdStringKind && RHSKind == EmptyKind)
|
|
return *LHS.stdString;
|
|
|
|
// If we're storing a formatv_object, we can avoid an extra copy by formatting
|
|
// it immediately and returning the result.
|
|
if (LHSKind == FormatvObjectKind && RHSKind == EmptyKind)
|
|
return LHS.formatvObject->str();
|
|
|
|
// Otherwise, flatten and copy the contents first.
|
|
SmallString<256> Vec;
|
|
return toStringRef(Vec).str();
|
|
}
|
|
|
|
void Twine::toVector(SmallVectorImpl<char> &Out) const {
|
|
raw_svector_ostream OS(Out);
|
|
print(OS);
|
|
}
|
|
|
|
StringRef Twine::toNullTerminatedStringRef(SmallVectorImpl<char> &Out) const {
|
|
if (isUnary()) {
|
|
switch (getLHSKind()) {
|
|
case CStringKind:
|
|
// Already null terminated, yay!
|
|
return StringRef(LHS.cString);
|
|
case StdStringKind: {
|
|
const std::string *str = LHS.stdString;
|
|
return StringRef(str->c_str(), str->size());
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
toVector(Out);
|
|
Out.push_back(0);
|
|
Out.pop_back();
|
|
return StringRef(Out.data(), Out.size());
|
|
}
|
|
|
|
void Twine::printOneChild(raw_ostream &OS, Child Ptr,
|
|
NodeKind Kind) const {
|
|
switch (Kind) {
|
|
case Twine::NullKind: break;
|
|
case Twine::EmptyKind: break;
|
|
case Twine::TwineKind:
|
|
Ptr.twine->print(OS);
|
|
break;
|
|
case Twine::CStringKind:
|
|
OS << Ptr.cString;
|
|
break;
|
|
case Twine::StdStringKind:
|
|
OS << *Ptr.stdString;
|
|
break;
|
|
case Twine::StringRefKind:
|
|
OS << *Ptr.stringRef;
|
|
break;
|
|
case Twine::SmallStringKind:
|
|
OS << *Ptr.smallString;
|
|
break;
|
|
case Twine::FormatvObjectKind:
|
|
OS << *Ptr.formatvObject;
|
|
break;
|
|
case Twine::CharKind:
|
|
OS << Ptr.character;
|
|
break;
|
|
case Twine::DecUIKind:
|
|
OS << Ptr.decUI;
|
|
break;
|
|
case Twine::DecIKind:
|
|
OS << Ptr.decI;
|
|
break;
|
|
case Twine::DecULKind:
|
|
OS << *Ptr.decUL;
|
|
break;
|
|
case Twine::DecLKind:
|
|
OS << *Ptr.decL;
|
|
break;
|
|
case Twine::DecULLKind:
|
|
OS << *Ptr.decULL;
|
|
break;
|
|
case Twine::DecLLKind:
|
|
OS << *Ptr.decLL;
|
|
break;
|
|
case Twine::UHexKind:
|
|
OS.write_hex(*Ptr.uHex);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void Twine::printOneChildRepr(raw_ostream &OS, Child Ptr,
|
|
NodeKind Kind) const {
|
|
switch (Kind) {
|
|
case Twine::NullKind:
|
|
OS << "null"; break;
|
|
case Twine::EmptyKind:
|
|
OS << "empty"; break;
|
|
case Twine::TwineKind:
|
|
OS << "rope:";
|
|
Ptr.twine->printRepr(OS);
|
|
break;
|
|
case Twine::CStringKind:
|
|
OS << "cstring:\""
|
|
<< Ptr.cString << "\"";
|
|
break;
|
|
case Twine::StdStringKind:
|
|
OS << "std::string:\"" << *Ptr.stdString << "\"";
|
|
break;
|
|
case Twine::StringRefKind:
|
|
OS << "stringref:\"" << *Ptr.stringRef << "\"";
|
|
break;
|
|
case Twine::SmallStringKind:
|
|
OS << "smallstring:\"" << *Ptr.smallString << "\"";
|
|
break;
|
|
case Twine::FormatvObjectKind:
|
|
OS << "formatv:\"" << *Ptr.formatvObject << "\"";
|
|
break;
|
|
case Twine::CharKind:
|
|
OS << "char:\"" << Ptr.character << "\"";
|
|
break;
|
|
case Twine::DecUIKind:
|
|
OS << "decUI:\"" << Ptr.decUI << "\"";
|
|
break;
|
|
case Twine::DecIKind:
|
|
OS << "decI:\"" << Ptr.decI << "\"";
|
|
break;
|
|
case Twine::DecULKind:
|
|
OS << "decUL:\"" << *Ptr.decUL << "\"";
|
|
break;
|
|
case Twine::DecLKind:
|
|
OS << "decL:\"" << *Ptr.decL << "\"";
|
|
break;
|
|
case Twine::DecULLKind:
|
|
OS << "decULL:\"" << *Ptr.decULL << "\"";
|
|
break;
|
|
case Twine::DecLLKind:
|
|
OS << "decLL:\"" << *Ptr.decLL << "\"";
|
|
break;
|
|
case Twine::UHexKind:
|
|
OS << "uhex:\"" << Ptr.uHex << "\"";
|
|
break;
|
|
}
|
|
}
|
|
|
|
void Twine::print(raw_ostream &OS) const {
|
|
printOneChild(OS, LHS, getLHSKind());
|
|
printOneChild(OS, RHS, getRHSKind());
|
|
}
|
|
|
|
void Twine::printRepr(raw_ostream &OS) const {
|
|
OS << "(Twine ";
|
|
printOneChildRepr(OS, LHS, getLHSKind());
|
|
OS << " ";
|
|
printOneChildRepr(OS, RHS, getRHSKind());
|
|
OS << ")";
|
|
}
|
|
|
|
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
|
|
LLVM_DUMP_METHOD void Twine::dump() const {
|
|
print(dbgs());
|
|
}
|
|
|
|
LLVM_DUMP_METHOD void Twine::dumpRepr() const {
|
|
printRepr(dbgs());
|
|
}
|
|
#endif
|