diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h index f184fb5e1df..5b1db209caf 100644 --- a/include/llvm/ADT/APInt.h +++ b/include/llvm/ADT/APInt.h @@ -20,7 +20,6 @@ #include #include #include -#include namespace llvm { class FoldingSetNodeID; @@ -1753,13 +1752,6 @@ public: toString(Str, Radix, true, false); } - /// Return the APInt as a std::string. - /// - /// Note that this is an inefficient method. It is better to pass in a - /// SmallVector/SmallString to the methods above to avoid thrashing the heap - /// for the string. - std::string toString(unsigned Radix, bool Signed) const; - /// \returns a byte-swapped representation of this APInt Value. APInt byteSwap() const; diff --git a/include/llvm/ADT/APSInt.h b/include/llvm/ADT/APSInt.h index f7af13205e3..1509d472f13 100644 --- a/include/llvm/ADT/APSInt.h +++ b/include/llvm/ADT/APSInt.h @@ -82,11 +82,6 @@ public: void toString(SmallVectorImpl &Str, unsigned Radix = 10) const { APInt::toString(Str, Radix, isSigned()); } - /// Converts an APInt to a std::string. This is an inefficient - /// method; you should prefer passing in a SmallString instead. - std::string toString(unsigned Radix) const { - return APInt::toString(Radix, isSigned()); - } using APInt::toString; /// Get the correctly-extended \c int64_t value. diff --git a/include/llvm/ADT/StringExtras.h b/include/llvm/ADT/StringExtras.h index 68e89508cba..6bda25b8531 100644 --- a/include/llvm/ADT/StringExtras.h +++ b/include/llvm/ADT/StringExtras.h @@ -13,6 +13,7 @@ #ifndef LLVM_ADT_STRINGEXTRAS_H #define LLVM_ADT_STRINGEXTRAS_H +#include "llvm/ADT/APSInt.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" @@ -296,6 +297,17 @@ inline std::string itostr(int64_t X) { return utostr(static_cast(X)); } +inline std::string toString(const APInt &I, unsigned Radix, bool Signed, + bool formatAsCLiteral = false) { + SmallString<40> S; + I.toString(S, Radix, Signed, formatAsCLiteral); + return std::string(S.str()); +} + +inline std::string toString(const APSInt &I, unsigned Radix) { + return toString(I, Radix, I.isSigned()); +} + /// StrInStrNoCase - Portable version of strcasestr. Locates the first /// occurrence of string 's1' in string 's2', ignoring case. Returns /// the offset of s2 in s1 or npos if s2 cannot be found. diff --git a/lib/CodeGen/GlobalISel/GISelKnownBits.cpp b/lib/CodeGen/GlobalISel/GISelKnownBits.cpp index 558bb6fd78c..a7f0d5fde12 100644 --- a/lib/CodeGen/GlobalISel/GISelKnownBits.cpp +++ b/lib/CodeGen/GlobalISel/GISelKnownBits.cpp @@ -88,10 +88,10 @@ LLVM_ATTRIBUTE_UNUSED static void dumpResult(const MachineInstr &MI, const KnownBits &Known, unsigned Depth) { dbgs() << "[" << Depth << "] Compute known bits: " << MI << "[" << Depth << "] Computed for: " << MI << "[" << Depth << "] Known: 0x" - << (Known.Zero | Known.One).toString(16, false) << "\n" - << "[" << Depth << "] Zero: 0x" << Known.Zero.toString(16, false) + << toString(Known.Zero | Known.One, 16, false) << "\n" + << "[" << Depth << "] Zero: 0x" << toString(Known.Zero, 16, false) << "\n" - << "[" << Depth << "] One: 0x" << Known.One.toString(16, false) + << "[" << Depth << "] One: 0x" << toString(Known.One, 16, false) << "\n"; } diff --git a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index c7fa1d67727..ace475dbe86 100644 --- a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -1930,7 +1930,7 @@ const MCExpr *TargetLoweringObjectFileCOFF::lowerRelativeReference( static std::string APIntToHexString(const APInt &AI) { unsigned Width = (AI.getBitWidth() / 8) * 2; - std::string HexString = AI.toString(16, /*Signed=*/false); + std::string HexString = toString(AI, 16, /*Signed=*/false); llvm::transform(HexString, HexString.begin(), tolower); unsigned Size = HexString.size(); assert(Width >= Size && "hex string is too large!"); diff --git a/lib/Support/APInt.cpp b/lib/Support/APInt.cpp index 462d19d2e7b..a8a950f0974 100644 --- a/lib/Support/APInt.cpp +++ b/lib/Support/APInt.cpp @@ -2281,14 +2281,6 @@ void APInt::toString(SmallVectorImpl &Str, unsigned Radix, std::reverse(Str.begin()+StartDig, Str.end()); } -/// Returns the APInt as a std::string. Note that this is an inefficient method. -/// It is better to pass in a SmallVector/SmallString to the methods above. -std::string APInt::toString(unsigned Radix = 10, bool Signed = true) const { - SmallString<40> S; - toString(S, Radix, Signed, /* formatAsCLiteral = */false); - return std::string(S.str()); -} - #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) LLVM_DUMP_METHOD void APInt::dump() const { SmallString<40> S, U; diff --git a/lib/Target/X86/X86MCInstLower.cpp b/lib/Target/X86/X86MCInstLower.cpp index 89fa3ae3a3f..7d916f917d5 100644 --- a/lib/Target/X86/X86MCInstLower.cpp +++ b/lib/Target/X86/X86MCInstLower.cpp @@ -2167,7 +2167,7 @@ static void addConstantComments(const MachineInstr *MI, const MachineOperand &DstOp = MI->getOperand(0); CS << X86ATTInstPrinter::getRegisterName(DstOp.getReg()) << " = "; if (auto *CF = dyn_cast(C)) { - CS << "0x" << CF->getValueAPF().bitcastToAPInt().toString(16, false); + CS << "0x" << toString(CF->getValueAPF().bitcastToAPInt(), 16, false); OutStreamer.AddComment(CS.str()); } } diff --git a/lib/Transforms/IPO/OpenMPOpt.cpp b/lib/Transforms/IPO/OpenMPOpt.cpp index 061deaf62c9..87440d7557f 100644 --- a/lib/Transforms/IPO/OpenMPOpt.cpp +++ b/lib/Transforms/IPO/OpenMPOpt.cpp @@ -585,7 +585,7 @@ struct OpenMPOpt { return ORA << "OpenMP ICV " << ore::NV("OpenMPICV", ICVInfo.Name) << " Value: " << (ICVInfo.InitValue - ? ICVInfo.InitValue->getValue().toString(10, true) + ? toString(ICVInfo.InitValue->getValue(), 10, true) : "IMPLEMENTATION_DEFINED"); }; diff --git a/tools/llvm-exegesis/lib/BenchmarkResult.cpp b/tools/llvm-exegesis/lib/BenchmarkResult.cpp index 7ceef254e60..4a4c2d6f3c5 100644 --- a/tools/llvm-exegesis/lib/BenchmarkResult.cpp +++ b/tools/llvm-exegesis/lib/BenchmarkResult.cpp @@ -255,7 +255,7 @@ template <> struct ScalarTraits { raw_ostream &Out) { YamlContext &Context = getTypedContext(Ctx); Out << Context.getRegName(RV.Register) << "=0x" - << RV.Value.toString(kRadix, kSigned); + << toString(RV.Value, kRadix, kSigned); } static StringRef input(StringRef String, void *Ctx, diff --git a/tools/llvm-pdbutil/MinimalSymbolDumper.cpp b/tools/llvm-pdbutil/MinimalSymbolDumper.cpp index 787785c34b7..17bc53de247 100644 --- a/tools/llvm-pdbutil/MinimalSymbolDumper.cpp +++ b/tools/llvm-pdbutil/MinimalSymbolDumper.cpp @@ -559,7 +559,7 @@ Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, P.format(" `{0}`", Constant.Name); AutoIndent Indent(P, 7); P.formatLine("type = {0}, value = {1}", typeIndex(Constant.Type), - Constant.Value.toString(10)); + toString(Constant.Value, 10)); return Error::success(); } diff --git a/tools/llvm-pdbutil/MinimalTypeDumper.cpp b/tools/llvm-pdbutil/MinimalTypeDumper.cpp index 8e46a97272d..08006e9c62d 100644 --- a/tools/llvm-pdbutil/MinimalTypeDumper.cpp +++ b/tools/llvm-pdbutil/MinimalTypeDumper.cpp @@ -557,7 +557,7 @@ Error MinimalTypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR, Error MinimalTypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR, EnumeratorRecord &Enum) { P.format(" [{0} = {1}]", Enum.Name, - Enum.Value.toString(10, Enum.Value.isSigned())); + toString(Enum.Value, 10, Enum.Value.isSigned())); return Error::success(); } diff --git a/unittests/ADT/APIntTest.cpp b/unittests/ADT/APIntTest.cpp index ef5423e332e..947d9598bac 100644 --- a/unittests/ADT/APIntTest.cpp +++ b/unittests/ADT/APIntTest.cpp @@ -1461,7 +1461,10 @@ TEST(APIntTest, mul_clear) { APInt ValC(65, 0); ValC = ValA * ValB; ValA *= ValB; - EXPECT_EQ(ValA.toString(10, false), ValC.toString(10, false)); + SmallString<16> StrA, StrC; + ValA.toString(StrA, 10, false); + ValC.toString(StrC, 10, false); + EXPECT_EQ(std::string(StrA), std::string(StrC)); } TEST(APIntTest, Rotate) { diff --git a/unittests/ADT/StringExtrasTest.cpp b/unittests/ADT/StringExtrasTest.cpp index 9816273524f..206392c3a27 100644 --- a/unittests/ADT/StringExtrasTest.cpp +++ b/unittests/ADT/StringExtrasTest.cpp @@ -229,3 +229,48 @@ TEST(StringExtrasTest, ListSeparator) { S = LS2; EXPECT_EQ(S, " "); } + +TEST(StringExtrasTest, toStringAPInt) { + bool isSigned; + + EXPECT_EQ(toString(APInt(8, 0), 2, true, true), "0b0"); + EXPECT_EQ(toString(APInt(8, 0), 8, true, true), "00"); + EXPECT_EQ(toString(APInt(8, 0), 10, true, true), "0"); + EXPECT_EQ(toString(APInt(8, 0), 16, true, true), "0x0"); + EXPECT_EQ(toString(APInt(8, 0), 36, true, false), "0"); + + isSigned = false; + EXPECT_EQ(toString(APInt(8, 255, isSigned), 2, isSigned, true), "0b11111111"); + EXPECT_EQ(toString(APInt(8, 255, isSigned), 8, isSigned, true), "0377"); + EXPECT_EQ(toString(APInt(8, 255, isSigned), 10, isSigned, true), "255"); + EXPECT_EQ(toString(APInt(8, 255, isSigned), 16, isSigned, true), "0xFF"); + EXPECT_EQ(toString(APInt(8, 255, isSigned), 36, isSigned, false), "73"); + + isSigned = true; + EXPECT_EQ(toString(APInt(8, 255, isSigned), 2, isSigned, true), "-0b1"); + EXPECT_EQ(toString(APInt(8, 255, isSigned), 8, isSigned, true), "-01"); + EXPECT_EQ(toString(APInt(8, 255, isSigned), 10, isSigned, true), "-1"); + EXPECT_EQ(toString(APInt(8, 255, isSigned), 16, isSigned, true), "-0x1"); + EXPECT_EQ(toString(APInt(8, 255, isSigned), 36, isSigned, false), "-1"); +} + +TEST(StringExtrasTest, toStringAPSInt) { + bool isUnsigned; + + EXPECT_EQ(toString(APSInt(APInt(8, 0), false), 2), "0"); + EXPECT_EQ(toString(APSInt(APInt(8, 0), false), 8), "0"); + EXPECT_EQ(toString(APSInt(APInt(8, 0), false), 10), "0"); + EXPECT_EQ(toString(APSInt(APInt(8, 0), false), 16), "0"); + + isUnsigned = true; + EXPECT_EQ(toString(APSInt(APInt(8, 255), isUnsigned), 2), "11111111"); + EXPECT_EQ(toString(APSInt(APInt(8, 255), isUnsigned), 8), "377"); + EXPECT_EQ(toString(APSInt(APInt(8, 255), isUnsigned), 10), "255"); + EXPECT_EQ(toString(APSInt(APInt(8, 255), isUnsigned), 16), "FF"); + + isUnsigned = false; + EXPECT_EQ(toString(APSInt(APInt(8, 255), isUnsigned), 2), "-1"); + EXPECT_EQ(toString(APSInt(APInt(8, 255), isUnsigned), 8), "-1"); + EXPECT_EQ(toString(APSInt(APInt(8, 255), isUnsigned), 10), "-1"); + EXPECT_EQ(toString(APSInt(APInt(8, 255), isUnsigned), 16), "-1"); +} \ No newline at end of file