Revert "[ADT] Make Twine's copy constructor private."

This reverts commit 4e4ee1c507e2707bb3c208e1e1b6551c3015cbf5.

This is failing due to some code that isn't built on MSVC
so I didn't catch.  Not immediately obvious how to fix this
at first glance, so I'm reverting for now.

llvm-svn: 315536
This commit is contained in:
Zachary Turner 2017-10-11 23:54:34 +00:00
parent 044fbfa38a
commit 0cc2a53e00
17 changed files with 47 additions and 72 deletions

View File

@ -79,10 +79,6 @@ namespace llvm {
/// overloads) to guarantee that particularly important cases (cstring plus /// overloads) to guarantee that particularly important cases (cstring plus
/// StringRef) codegen as desired. /// StringRef) codegen as desired.
class Twine { class Twine {
friend Twine operator+(const char *LHS, const StringRef &RHS);
friend Twine operator+(const StringRef &LHS, const char *RHS);
friend Twine operator+(const StringRef &LHS, const StringRef &RHS);
/// NodeKind - Represent the type of an argument. /// NodeKind - Represent the type of an argument.
enum NodeKind : unsigned char { enum NodeKind : unsigned char {
/// An empty string; the result of concatenating anything with it is also /// An empty string; the result of concatenating anything with it is also
@ -173,12 +169,6 @@ namespace llvm {
assert(isNullary() && "Invalid kind!"); assert(isNullary() && "Invalid kind!");
} }
// While there are some valid use cases for copying Twines, most of them
// are confined to the implementation of Twine itself, and Twine itself is
// not intended to be publicly copyable since it can very easily lead to
// dangling pointers / references.
Twine(const Twine &) = default;
/// Construct a binary twine. /// Construct a binary twine.
explicit Twine(const Twine &LHS, const Twine &RHS) explicit Twine(const Twine &LHS, const Twine &RHS)
: LHSKind(TwineKind), RHSKind(TwineKind) { : LHSKind(TwineKind), RHSKind(TwineKind) {
@ -266,6 +256,8 @@ namespace llvm {
assert(isValid() && "Invalid twine!"); assert(isValid() && "Invalid twine!");
} }
Twine(const Twine &) = default;
/// Construct from a C string. /// Construct from a C string.
/// ///
/// We take care here to optimize "" into the empty twine -- this will be /// We take care here to optimize "" into the empty twine -- this will be
@ -282,8 +274,6 @@ namespace llvm {
assert(isValid() && "Invalid twine!"); assert(isValid() && "Invalid twine!");
} }
Twine(Twine &&Other) = default;
/// Construct from an std::string. /// Construct from an std::string.
/*implicit*/ Twine(const std::string &Str) /*implicit*/ Twine(const std::string &Str)
: LHSKind(StdStringKind), RHSKind(EmptyKind) { : LHSKind(StdStringKind), RHSKind(EmptyKind) {
@ -387,14 +377,6 @@ namespace llvm {
assert(isValid() && "Invalid twine!"); assert(isValid() && "Invalid twine!");
} }
/// Construct as the concatenation of two StringRefs.
/*implicit*/ Twine(const StringRef &LHS, const StringRef &RHS)
: LHSKind(StringRefKind), RHSKind(StringRefKind) {
this->LHS.stringRef = &LHS;
this->RHS.stringRef = &RHS;
assert(isValid() && "Invalid twine!");
}
/// Since the intended use of twines is as temporary objects, assignments /// Since the intended use of twines is as temporary objects, assignments
/// when concatenating might cause undefined behavior or stack corruptions /// when concatenating might cause undefined behavior or stack corruptions
Twine &operator=(const Twine &) = delete; Twine &operator=(const Twine &) = delete;
@ -505,10 +487,6 @@ namespace llvm {
/// Dump the representation of this twine to stderr. /// Dump the representation of this twine to stderr.
void dumpRepr() const; void dumpRepr() const;
friend inline Twine operator+(const Twine &LHS, const Twine &RHS) {
return LHS.concat(RHS);
}
/// @} /// @}
}; };
@ -544,6 +522,10 @@ namespace llvm {
return Twine(NewLHS, NewLHSKind, NewRHS, NewRHSKind); return Twine(NewLHS, NewLHSKind, NewRHS, NewRHSKind);
} }
inline Twine operator+(const Twine &LHS, const Twine &RHS) {
return LHS.concat(RHS);
}
/// Additional overload to guarantee simplified codegen; this is equivalent to /// Additional overload to guarantee simplified codegen; this is equivalent to
/// concat(). /// concat().
@ -551,11 +533,10 @@ namespace llvm {
return Twine(LHS, RHS); return Twine(LHS, RHS);
} }
inline Twine operator+(const StringRef &LHS, const char *RHS) { /// Additional overload to guarantee simplified codegen; this is equivalent to
return Twine(LHS, RHS); /// concat().
}
inline Twine operator+(const StringRef &LHS, const StringRef &RHS) { inline Twine operator+(const StringRef &LHS, const char *RHS) {
return Twine(LHS, RHS); return Twine(LHS, RHS);
} }

View File

@ -962,7 +962,7 @@ public:
/// Diagnostic information for unsupported feature in backend. /// Diagnostic information for unsupported feature in backend.
class DiagnosticInfoUnsupported : public DiagnosticInfoWithLocationBase { class DiagnosticInfoUnsupported : public DiagnosticInfoWithLocationBase {
private: private:
std::string Msg; Twine Msg;
public: public:
/// \p Fn is the function where the diagnostic is being emitted. \p Loc is /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
@ -976,13 +976,13 @@ public:
const DiagnosticLocation &Loc = DiagnosticLocation(), const DiagnosticLocation &Loc = DiagnosticLocation(),
DiagnosticSeverity Severity = DS_Error) DiagnosticSeverity Severity = DS_Error)
: DiagnosticInfoWithLocationBase(DK_Unsupported, Severity, Fn, Loc), : DiagnosticInfoWithLocationBase(DK_Unsupported, Severity, Fn, Loc),
Msg(Msg.str()) {} Msg(Msg) {}
static bool classof(const DiagnosticInfo *DI) { static bool classof(const DiagnosticInfo *DI) {
return DI->getKind() == DK_Unsupported; return DI->getKind() == DK_Unsupported;
} }
StringRef getMessage() const { return Msg; } const Twine &getMessage() const { return Msg; }
void print(DiagnosticPrinter &DP) const override; void print(DiagnosticPrinter &DP) const override;
}; };

View File

@ -65,8 +65,8 @@ public:
class GenericBinaryError : public ErrorInfo<GenericBinaryError, BinaryError> { class GenericBinaryError : public ErrorInfo<GenericBinaryError, BinaryError> {
public: public:
static char ID; static char ID;
GenericBinaryError(const Twine &Msg); GenericBinaryError(Twine Msg);
GenericBinaryError(const Twine &Msg, object_error ECOverride); GenericBinaryError(Twine Msg, object_error ECOverride);
const std::string &getMessage() const { return Msg; } const std::string &getMessage() const { return Msg; }
void log(raw_ostream &OS) const override; void log(raw_ostream &OS) const override;
private: private:

View File

@ -87,7 +87,7 @@ struct WinResHeaderSuffix {
class EmptyResError : public GenericBinaryError { class EmptyResError : public GenericBinaryError {
public: public:
EmptyResError(const Twine &Msg, object_error ECOverride) EmptyResError(Twine Msg, object_error ECOverride)
: GenericBinaryError(Msg, ECOverride) {} : GenericBinaryError(Msg, ECOverride) {}
}; };

View File

@ -931,7 +931,7 @@ Expected<T> handleExpected(Expected<T> ValOrErr, RecoveryFtor &&RecoveryPath,
/// This is useful in the base level of your program to allow clean termination /// This is useful in the base level of your program to allow clean termination
/// (allowing clean deallocation of resources, etc.), while reporting error /// (allowing clean deallocation of resources, etc.), while reporting error
/// information to the user. /// information to the user.
void logAllUnhandledErrors(Error E, raw_ostream &OS, const Twine &ErrorBanner); void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner);
/// Write all error messages (if any) in E to a string. The newline character /// Write all error messages (if any) in E to a string. The newline character
/// is used to separate error messages. /// is used to separate error messages.

View File

@ -28,7 +28,7 @@ public:
}; };
template <typename T> class provider_format_adapter : public format_adapter { template <typename T> class provider_format_adapter : public format_adapter {
T &Item; T Item;
public: public:
explicit provider_format_adapter(T &&Item) : Item(Item) {} explicit provider_format_adapter(T &&Item) : Item(Item) {}

View File

@ -60,10 +60,9 @@ std::string _object_error_category::message(int EV) const {
char BinaryError::ID = 0; char BinaryError::ID = 0;
char GenericBinaryError::ID = 0; char GenericBinaryError::ID = 0;
GenericBinaryError::GenericBinaryError(const Twine &Msg) : Msg(Msg.str()) {} GenericBinaryError::GenericBinaryError(Twine Msg) : Msg(Msg.str()) {}
GenericBinaryError::GenericBinaryError(const Twine &Msg, GenericBinaryError::GenericBinaryError(Twine Msg, object_error ECOverride)
object_error ECOverride)
: Msg(Msg.str()) { : Msg(Msg.str()) {
setErrorCode(make_error_code(ECOverride)); setErrorCode(make_error_code(ECOverride));
} }

View File

@ -54,7 +54,7 @@ char ErrorList::ID = 0;
char ECError::ID = 0; char ECError::ID = 0;
char StringError::ID = 0; char StringError::ID = 0;
void logAllUnhandledErrors(Error E, raw_ostream &OS, const Twine &ErrorBanner) { void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner) {
if (!E) if (!E)
return; return;
OS << ErrorBanner; OS << ErrorBanner;

View File

@ -120,10 +120,12 @@ void Twine::printOneChildRepr(raw_ostream &OS, Child Ptr,
<< Ptr.cString << "\""; << Ptr.cString << "\"";
break; break;
case Twine::StdStringKind: case Twine::StdStringKind:
OS << "std::string:\"" << *Ptr.stdString << "\""; OS << "std::string:\""
<< Ptr.stdString << "\"";
break; break;
case Twine::StringRefKind: case Twine::StringRefKind:
OS << "stringref:\"" << *Ptr.stringRef << "\""; OS << "stringref:\""
<< Ptr.stringRef << "\"";
break; break;
case Twine::SmallStringKind: case Twine::SmallStringKind:
OS << "smallstring:\"" << *Ptr.smallString << "\""; OS << "smallstring:\"" << *Ptr.smallString << "\"";

View File

@ -130,15 +130,18 @@ namespace {
class IRBuilderPrefixedInserter : public IRBuilderDefaultInserter { class IRBuilderPrefixedInserter : public IRBuilderDefaultInserter {
std::string Prefix; std::string Prefix;
const Twine getNameWithPrefix(const Twine &Name) const {
return Name.isTriviallyEmpty() ? Name : Prefix + Name;
}
public: public:
void SetNamePrefix(const Twine &P) { Prefix = P.str(); } void SetNamePrefix(const Twine &P) { Prefix = P.str(); }
protected: protected:
void InsertHelper(Instruction *I, const Twine &Name, BasicBlock *BB, void InsertHelper(Instruction *I, const Twine &Name, BasicBlock *BB,
BasicBlock::iterator InsertPt) const { BasicBlock::iterator InsertPt) const {
const Twine &Prefixed = Prefix + Name; IRBuilderDefaultInserter::InsertHelper(I, getNameWithPrefix(Name), BB,
IRBuilderDefaultInserter::InsertHelper( InsertPt);
I, Name.isTriviallyEmpty() ? Name : Prefixed, BB, InsertPt);
} }
}; };
@ -1352,8 +1355,7 @@ static void speculateSelectInstLoads(SelectInst &SI) {
/// This will return the BasePtr if that is valid, or build a new GEP /// This will return the BasePtr if that is valid, or build a new GEP
/// instruction using the IRBuilder if GEP-ing is needed. /// instruction using the IRBuilder if GEP-ing is needed.
static Value *buildGEP(IRBuilderTy &IRB, Value *BasePtr, static Value *buildGEP(IRBuilderTy &IRB, Value *BasePtr,
SmallVectorImpl<Value *> &Indices, SmallVectorImpl<Value *> &Indices, Twine NamePrefix) {
const Twine &NamePrefix) {
if (Indices.empty()) if (Indices.empty())
return BasePtr; return BasePtr;
@ -1378,7 +1380,7 @@ static Value *buildGEP(IRBuilderTy &IRB, Value *BasePtr,
static Value *getNaturalGEPWithType(IRBuilderTy &IRB, const DataLayout &DL, static Value *getNaturalGEPWithType(IRBuilderTy &IRB, const DataLayout &DL,
Value *BasePtr, Type *Ty, Type *TargetTy, Value *BasePtr, Type *Ty, Type *TargetTy,
SmallVectorImpl<Value *> &Indices, SmallVectorImpl<Value *> &Indices,
const Twine &NamePrefix) { Twine NamePrefix) {
if (Ty == TargetTy) if (Ty == TargetTy)
return buildGEP(IRB, BasePtr, Indices, NamePrefix); return buildGEP(IRB, BasePtr, Indices, NamePrefix);
@ -1423,7 +1425,7 @@ static Value *getNaturalGEPRecursively(IRBuilderTy &IRB, const DataLayout &DL,
Value *Ptr, Type *Ty, APInt &Offset, Value *Ptr, Type *Ty, APInt &Offset,
Type *TargetTy, Type *TargetTy,
SmallVectorImpl<Value *> &Indices, SmallVectorImpl<Value *> &Indices,
const Twine &NamePrefix) { Twine NamePrefix) {
if (Offset == 0) if (Offset == 0)
return getNaturalGEPWithType(IRB, DL, Ptr, Ty, TargetTy, Indices, return getNaturalGEPWithType(IRB, DL, Ptr, Ty, TargetTy, Indices,
NamePrefix); NamePrefix);
@ -1496,7 +1498,7 @@ static Value *getNaturalGEPRecursively(IRBuilderTy &IRB, const DataLayout &DL,
static Value *getNaturalGEPWithOffset(IRBuilderTy &IRB, const DataLayout &DL, static Value *getNaturalGEPWithOffset(IRBuilderTy &IRB, const DataLayout &DL,
Value *Ptr, APInt Offset, Type *TargetTy, Value *Ptr, APInt Offset, Type *TargetTy,
SmallVectorImpl<Value *> &Indices, SmallVectorImpl<Value *> &Indices,
const Twine &NamePrefix) { Twine NamePrefix) {
PointerType *Ty = cast<PointerType>(Ptr->getType()); PointerType *Ty = cast<PointerType>(Ptr->getType());
// Don't consider any GEPs through an i8* as natural unless the TargetTy is // Don't consider any GEPs through an i8* as natural unless the TargetTy is
@ -1534,8 +1536,7 @@ static Value *getNaturalGEPWithOffset(IRBuilderTy &IRB, const DataLayout &DL,
/// a single GEP as possible, thus making each GEP more independent of the /// a single GEP as possible, thus making each GEP more independent of the
/// surrounding code. /// surrounding code.
static Value *getAdjustedPtr(IRBuilderTy &IRB, const DataLayout &DL, Value *Ptr, static Value *getAdjustedPtr(IRBuilderTy &IRB, const DataLayout &DL, Value *Ptr,
APInt Offset, Type *PointerTy, APInt Offset, Type *PointerTy, Twine NamePrefix) {
const Twine &NamePrefix) {
// Even though we don't look through PHI nodes, we could be called on an // Even though we don't look through PHI nodes, we could be called on an
// instruction in an unreachable block, which may be on a cycle. // instruction in an unreachable block, which may be on a cycle.
SmallPtrSet<Value *, 4> Visited; SmallPtrSet<Value *, 4> Visited;

View File

@ -195,12 +195,12 @@ bool HadError = false;
std::string ToolName; std::string ToolName;
} // anonymous namespace } // anonymous namespace
static void error(const Twine &Message, const Twine &Path = Twine()) { static void error(Twine Message, Twine Path = Twine()) {
HadError = true; HadError = true;
errs() << ToolName << ": " << Path << ": " << Message << ".\n"; errs() << ToolName << ": " << Path << ": " << Message << ".\n";
} }
static bool error(std::error_code EC, const Twine &Path = Twine()) { static bool error(std::error_code EC, Twine Path = Twine()) {
if (EC) { if (EC) {
error(EC.message(), Path); error(EC.message(), Path);
return true; return true;

View File

@ -428,15 +428,15 @@ void initRelocations(RelocationSection<ELFT> *Relocs,
} }
} }
SectionBase *SectionTableRef::getSection(uint16_t Index, const Twine &ErrMsg) { SectionBase *SectionTableRef::getSection(uint16_t Index, Twine ErrMsg) {
if (Index == SHN_UNDEF || Index > Sections.size()) if (Index == SHN_UNDEF || Index > Sections.size())
error(ErrMsg); error(ErrMsg);
return Sections[Index - 1].get(); return Sections[Index - 1].get();
} }
template <class T> template <class T>
T *SectionTableRef::getSectionOfType(uint16_t Index, const Twine &IndexErrMsg, T *SectionTableRef::getSectionOfType(uint16_t Index, Twine IndexErrMsg,
const Twine &TypeErrMsg) { Twine TypeErrMsg) {
if (T *Sec = llvm::dyn_cast<T>(getSection(Index, IndexErrMsg))) if (T *Sec = llvm::dyn_cast<T>(getSection(Index, IndexErrMsg)))
return Sec; return Sec;
error(TypeErrMsg); error(TypeErrMsg);

View File

@ -29,11 +29,11 @@ public:
: Sections(Secs) {} : Sections(Secs) {}
SectionTableRef(const SectionTableRef &) = default; SectionTableRef(const SectionTableRef &) = default;
SectionBase *getSection(uint16_t Index, const llvm::Twine &ErrMsg); SectionBase *getSection(uint16_t Index, llvm::Twine ErrMsg);
template <class T> template <class T>
T *getSectionOfType(uint16_t Index, const llvm::Twine &IndexErrMsg, T *getSectionOfType(uint16_t Index, llvm::Twine IndexErrMsg,
const llvm::Twine &TypeErrMsg); llvm::Twine TypeErrMsg);
}; };
class SectionBase { class SectionBase {

View File

@ -27,7 +27,7 @@ static StringRef ToolName;
namespace llvm { namespace llvm {
LLVM_ATTRIBUTE_NORETURN void error(const Twine &Message) { LLVM_ATTRIBUTE_NORETURN void error(Twine Message) {
errs() << ToolName << ": " << Message << ".\n"; errs() << ToolName << ": " << Message << ".\n";
errs().flush(); errs().flush();
exit(1); exit(1);

View File

@ -14,7 +14,7 @@
namespace llvm { namespace llvm {
LLVM_ATTRIBUTE_NORETURN extern void error(const Twine &Message); LLVM_ATTRIBUTE_NORETURN extern void error(Twine Message);
// This is taken from llvm-readobj. // This is taken from llvm-readobj.
// [see here](llvm/tools/llvm-readobj/llvm-readobj.h:38) // [see here](llvm/tools/llvm-readobj/llvm-readobj.h:38)

View File

@ -88,14 +88,6 @@ TEST(TwineTest, Concat) {
repr(Twine("a").concat(Twine(SmallString<3>("b")).concat(Twine("c"))))); repr(Twine("a").concat(Twine(SmallString<3>("b")).concat(Twine("c")))));
} }
TEST(TwineTest, Operators) {
EXPECT_EQ(R"((Twine cstring:"a" stringref:"b"))", repr("a" + StringRef("b")));
EXPECT_EQ(R"((Twine stringref:"a" cstring:"b"))", repr(StringRef("a") + "b"));
EXPECT_EQ(R"((Twine stringref:"a" stringref:"b"))",
repr(StringRef("a") + StringRef("b")));
}
TEST(TwineTest, toNullTerminatedStringRef) { TEST(TwineTest, toNullTerminatedStringRef) {
SmallString<8> storage; SmallString<8> storage;
EXPECT_EQ(0, *Twine("hello").toNullTerminatedStringRef(storage).end()); EXPECT_EQ(0, *Twine("hello").toNullTerminatedStringRef(storage).end());

View File

@ -169,7 +169,7 @@ void RegisterBankEmitter::emitBaseClassDefinition(
/// to the class. /// to the class.
static void visitRegisterBankClasses( static void visitRegisterBankClasses(
CodeGenRegBank &RegisterClassHierarchy, const CodeGenRegisterClass *RC, CodeGenRegBank &RegisterClassHierarchy, const CodeGenRegisterClass *RC,
const Twine &Kind, const Twine Kind,
std::function<void(const CodeGenRegisterClass *, StringRef)> VisitFn, std::function<void(const CodeGenRegisterClass *, StringRef)> VisitFn,
SmallPtrSetImpl<const CodeGenRegisterClass *> &VisitedRCs) { SmallPtrSetImpl<const CodeGenRegisterClass *> &VisitedRCs) {
@ -183,7 +183,7 @@ static void visitRegisterBankClasses(
for (const auto &PossibleSubclass : RegisterClassHierarchy.getRegClasses()) { for (const auto &PossibleSubclass : RegisterClassHierarchy.getRegClasses()) {
std::string TmpKind = std::string TmpKind =
(Kind + " (" + PossibleSubclass.getName() + ")").str(); (Twine(Kind) + " (" + PossibleSubclass.getName() + ")").str();
// Visit each subclass of an explicitly named class. // Visit each subclass of an explicitly named class.
if (RC != &PossibleSubclass && RC->hasSubClass(&PossibleSubclass)) if (RC != &PossibleSubclass && RC->hasSubClass(&PossibleSubclass))