Author: Simon Pilgrim
Date: 2021-06-11T13:19:15+01:00
New Revision: 61cdaf66fe22be2b5942ddee4f46a998b4f3ee29

URL: 
https://github.com/llvm/llvm-project/commit/61cdaf66fe22be2b5942ddee4f46a998b4f3ee29
DIFF: 
https://github.com/llvm/llvm-project/commit/61cdaf66fe22be2b5942ddee4f46a998b4f3ee29.diff

LOG: [ADT] Remove APInt/APSInt toString() std::string variants

<string> is currently the highest impact header in a clang+llvm build:

https://commondatastorage.googleapis.com/chromium-browser-clang/llvm-include-analysis.html

One of the most common places this is being included is the APInt.h header, 
which needs it for an old toString() implementation that returns std::string - 
an inefficient method compared to the SmallString versions that it actually 
wraps.

This patch replaces these APInt/APSInt methods with a pair of llvm::toString() 
helpers inside StringExtras.h, adjusts users accordingly and removes the 
<string> from APInt.h - I was hoping that more of these users could be 
converted to use the SmallString methods, but it appears that most end up 
creating a std::string anyhow. I avoided trying to use the raw_ostream << 
operators as well as I didn't want to lose having the integer radix explicit in 
the code.

Differential Revision: https://reviews.llvm.org/D103888

Added: 
    

Modified: 
    clang-tools-extra/clang-tidy/abseil/DurationRewriter.cpp
    
clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp
    clang-tools-extra/clangd/DumpAST.cpp
    clang-tools-extra/clangd/Hover.cpp
    clang/include/clang/ASTMatchers/ASTMatchers.h
    clang/lib/AST/ASTDiagnostic.cpp
    clang/lib/AST/ASTStructuralEquivalence.cpp
    clang/lib/AST/ExprConstant.cpp
    clang/lib/AST/StmtPrinter.cpp
    clang/lib/AST/TemplateBase.cpp
    clang/lib/AST/TextNodeDumper.cpp
    clang/lib/Analysis/ThreadSafetyCommon.cpp
    clang/lib/CodeGen/CGBuiltin.cpp
    clang/lib/CodeGen/CodeGenModule.cpp
    clang/lib/Frontend/CompilerInvocation.cpp
    clang/lib/Frontend/InitPreprocessor.cpp
    clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp
    clang/lib/Lex/PPExpressions.cpp
    clang/lib/Sema/SemaCast.cpp
    clang/lib/Sema/SemaChecking.cpp
    clang/lib/Sema/SemaConcept.cpp
    clang/lib/Sema/SemaDecl.cpp
    clang/lib/Sema/SemaDeclAttr.cpp
    clang/lib/Sema/SemaDeclCXX.cpp
    clang/lib/Sema/SemaExpr.cpp
    clang/lib/Sema/SemaExprCXX.cpp
    clang/lib/Sema/SemaInit.cpp
    clang/lib/Sema/SemaOpenMP.cpp
    clang/lib/Sema/SemaStmt.cpp
    clang/lib/Sema/SemaStmtAsm.cpp
    clang/lib/Sema/SemaTemplate.cpp
    clang/lib/Sema/SemaType.cpp
    clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
    clang/unittests/StaticAnalyzer/RangeSetTest.cpp
    clang/unittests/Tooling/RecursiveASTVisitorTestPostOrderVisitor.cpp
    clang/unittests/Tooling/RecursiveASTVisitorTests/CallbacksCommon.h
    llvm/include/llvm/ADT/APInt.h
    llvm/include/llvm/ADT/APSInt.h
    llvm/include/llvm/ADT/StringExtras.h
    llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp
    llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
    llvm/lib/Support/APInt.cpp
    llvm/lib/Target/X86/X86MCInstLower.cpp
    llvm/lib/Transforms/IPO/OpenMPOpt.cpp
    llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp
    llvm/tools/llvm-pdbutil/MinimalSymbolDumper.cpp
    llvm/tools/llvm-pdbutil/MinimalTypeDumper.cpp
    llvm/unittests/ADT/APIntTest.cpp
    llvm/unittests/ADT/StringExtrasTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clang-tidy/abseil/DurationRewriter.cpp 
b/clang-tools-extra/clang-tidy/abseil/DurationRewriter.cpp
index 125812f4f3a81..84c7a9fa92471 100644
--- a/clang-tools-extra/clang-tidy/abseil/DurationRewriter.cpp
+++ b/clang-tools-extra/clang-tidy/abseil/DurationRewriter.cpp
@@ -208,7 +208,7 @@ stripFloatLiteralFraction(const MatchFinder::MatchResult 
&Result,
   if (const auto *LitFloat = llvm::dyn_cast<FloatingLiteral>(&Node))
     // Attempt to simplify a `Duration` factory call with a literal argument.
     if (llvm::Optional<llvm::APSInt> IntValue = truncateIfIntegral(*LitFloat))
-      return IntValue->toString(/*radix=*/10);
+      return toString(*IntValue, /*radix=*/10);
 
   return llvm::None;
 }

diff  --git 
a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp
 
b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp
index 1826e955f6a93..450b56135a78b 100644
--- 
a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp
+++ 
b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp
@@ -99,7 +99,7 @@ void ProBoundsConstantArrayIndexCheck::check(
 
   if (Index->isSigned() && Index->isNegative()) {
     diag(Matched->getExprLoc(), "std::array<> index %0 is negative")
-        << Index->toString(10);
+        << toString(*Index, 10);
     return;
   }
 
@@ -118,7 +118,7 @@ void ProBoundsConstantArrayIndexCheck::check(
     diag(Matched->getExprLoc(),
          "std::array<> index %0 is past the end of the array "
          "(which contains %1 elements)")
-        << Index->toString(10) << ArraySize.toString(10, false);
+        << toString(*Index, 10) << toString(ArraySize, 10, false);
   }
 }
 

diff  --git a/clang-tools-extra/clangd/DumpAST.cpp 
b/clang-tools-extra/clangd/DumpAST.cpp
index 40ac8afbb5000..30b90d2e0b548 100644
--- a/clang-tools-extra/clangd/DumpAST.cpp
+++ b/clang-tools-extra/clangd/DumpAST.cpp
@@ -290,7 +290,7 @@ class DumpVisitor : public RecursiveASTVisitor<DumpVisitor> 
{
   }
   std::string getDetail(const TemplateArgumentLoc &TAL) {
     if (TAL.getArgument().getKind() == TemplateArgument::Integral)
-      return TAL.getArgument().getAsIntegral().toString(10);
+      return toString(TAL.getArgument().getAsIntegral(), 10);
     return "";
   }
   std::string getDetail(const TemplateName &TN) {

diff  --git a/clang-tools-extra/clangd/Hover.cpp 
b/clang-tools-extra/clangd/Hover.cpp
index 3651a3446fed4..8b14777173a0f 100644
--- a/clang-tools-extra/clangd/Hover.cpp
+++ b/clang-tools-extra/clangd/Hover.cpp
@@ -587,7 +587,7 @@ HoverInfo getHoverContents(const NamedDecl *D, const 
PrintingPolicy &PP,
   } else if (const auto *ECD = dyn_cast<EnumConstantDecl>(D)) {
     // Dependent enums (e.g. nested in template classes) don't have values yet.
     if (!ECD->getType()->isDependentType())
-      HI.Value = ECD->getInitVal().toString(10);
+      HI.Value = toString(ECD->getInitVal(), 10);
   }
 
   HI.Definition = printDefinition(D, PP);

diff  --git a/clang/include/clang/ASTMatchers/ASTMatchers.h 
b/clang/include/clang/ASTMatchers/ASTMatchers.h
index 4db562910c539..a13827df4405a 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -1213,7 +1213,7 @@ AST_MATCHER_P(TemplateArgument, equalsIntegralValue,
               std::string, Value) {
   if (Node.getKind() != TemplateArgument::Integral)
     return false;
-  return Node.getAsIntegral().toString(10) == Value;
+  return toString(Node.getAsIntegral(), 10) == Value;
 }
 
 /// Matches an Objective-C autorelease pool statement.

diff  --git a/clang/lib/AST/ASTDiagnostic.cpp b/clang/lib/AST/ASTDiagnostic.cpp
index 2bc731717b982..dc22481d0a84c 100644
--- a/clang/lib/AST/ASTDiagnostic.cpp
+++ b/clang/lib/AST/ASTDiagnostic.cpp
@@ -19,6 +19,7 @@
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/TemplateBase.h"
 #include "clang/AST/Type.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/raw_ostream.h"
 
 using namespace clang;
@@ -1756,7 +1757,7 @@ class TemplateDiff {
       if (FromIntType->isBooleanType()) {
         OS << ((FromInt == 0) ? "false" : "true");
       } else {
-        OS << FromInt.toString(10);
+        OS << toString(FromInt, 10);
       }
       return;
     }
@@ -1800,7 +1801,7 @@ class TemplateDiff {
       if (IntType->isBooleanType()) {
         OS << ((Val == 0) ? "false" : "true");
       } else {
-        OS << Val.toString(10);
+        OS << toString(Val, 10);
       }
     } else if (E) {
       PrintExpr(E);

diff  --git a/clang/lib/AST/ASTStructuralEquivalence.cpp 
b/clang/lib/AST/ASTStructuralEquivalence.cpp
index d004e443ae06a..c4ff05ba9325d 100644
--- a/clang/lib/AST/ASTStructuralEquivalence.cpp
+++ b/clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -86,6 +86,7 @@
 #include "llvm/ADT/APSInt.h"
 #include "llvm/ADT/None.h"
 #include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -1623,7 +1624,7 @@ static bool 
IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
                           diag::err_odr_tag_type_inconsistent))
             << Context.ToCtx.getTypeDeclType(D2);
         Context.Diag1(EC1->getLocation(), diag::note_odr_enumerator)
-            << EC1->getDeclName() << EC1->getInitVal().toString(10);
+            << EC1->getDeclName() << toString(EC1->getInitVal(), 10);
         Context.Diag2(D2->getLocation(), diag::note_odr_missing_enumerator);
       }
       return false;
@@ -1639,9 +1640,9 @@ static bool 
IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
                           diag::err_odr_tag_type_inconsistent))
             << Context.ToCtx.getTypeDeclType(D2);
         Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator)
-            << EC2->getDeclName() << EC2->getInitVal().toString(10);
+            << EC2->getDeclName() << toString(EC2->getInitVal(), 10);
         Context.Diag1(EC1->getLocation(), diag::note_odr_enumerator)
-            << EC1->getDeclName() << EC1->getInitVal().toString(10);
+            << EC1->getDeclName() << toString(EC1->getInitVal(), 10);
       }
       return false;
     }
@@ -1653,7 +1654,7 @@ static bool 
IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
                                            
diag::err_odr_tag_type_inconsistent))
           << Context.ToCtx.getTypeDeclType(D2);
       Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator)
-          << EC2->getDeclName() << EC2->getInitVal().toString(10);
+          << EC2->getDeclName() << toString(EC2->getInitVal(), 10);
       Context.Diag1(D1->getLocation(), diag::note_odr_missing_enumerator);
     }
     return false;

diff  --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 119b6f98dcf8d..a4d8fec09748d 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -2720,7 +2720,7 @@ static bool CheckedIntArithmetic(EvalInfo &Info, const 
Expr *E,
     if (Info.checkingForUndefinedBehavior())
       Info.Ctx.getDiagnostics().Report(E->getExprLoc(),
                                        diag::warn_integer_constant_overflow)
-          << Result.toString(10) << E->getType();
+          << toString(Result, 10) << E->getType();
     return HandleOverflow(Info, E, Value, E->getType());
   }
   return true;
@@ -6964,7 +6964,7 @@ class BufferToAPValueConverter {
   llvm::NoneType unrepresentableValue(QualType Ty, const APSInt &Val) {
     Info.FFDiag(BCE->getBeginLoc(),
                 diag::note_constexpr_bit_cast_unrepresentable_value)
-        << Ty << Val.toString(/*Radix=*/10);
+        << Ty << toString(Val, /*Radix=*/10);
     return None;
   }
 
@@ -9265,7 +9265,7 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const 
CallExpr *E,
       llvm::APInt::udivrem(OrigN, TSize, N, Remainder);
       if (Remainder) {
         Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
-            << Move << WChar << 0 << T << OrigN.toString(10, /*Signed*/false)
+            << Move << WChar << 0 << T << toString(OrigN, 10, /*Signed*/false)
             << (unsigned)TSize;
         return false;
       }
@@ -9279,7 +9279,7 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const 
CallExpr *E,
     if (N.ugt(RemainingSrcSize) || N.ugt(RemainingDestSize)) {
       Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
           << Move << WChar << (N.ugt(RemainingSrcSize) ? 1 : 2) << T
-          << N.toString(10, /*Signed*/false);
+          << toString(N, 10, /*Signed*/false);
       return false;
     }
     uint64_t NElems = N.getZExtValue();
@@ -9454,8 +9454,8 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const 
CXXNewExpr *E) {
           return ZeroInitialization(E);
 
         Info.FFDiag(*ArraySize, diag::note_constexpr_new_too_small)
-            << AllocBound.toString(10, /*Signed=*/false)
-            << InitBound.toString(10, /*Signed=*/false)
+            << toString(AllocBound, 10, /*Signed=*/false)
+            << toString(InitBound, 10, /*Signed=*/false)
             << (*ArraySize)->getSourceRange();
         return false;
       }

diff  --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index ed7f5763acde7..45b15171aa97c 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -47,6 +47,7 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/Compiler.h"
@@ -1122,7 +1123,7 @@ void StmtPrinter::VisitIntegerLiteral(IntegerLiteral 
*Node) {
   if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
     return;
   bool isSigned = Node->getType()->isSignedIntegerType();
-  OS << Node->getValue().toString(10, isSigned);
+  OS << toString(Node->getValue(), 10, isSigned);
 
   // Emit suffixes.  Integer literals are always a builtin integer type.
   switch (Node->getType()->castAs<BuiltinType>()->getKind()) {
@@ -1867,7 +1868,7 @@ void 
StmtPrinter::VisitUserDefinedLiteral(UserDefinedLiteral *Node) {
   case UserDefinedLiteral::LOK_Integer: {
     // Print integer literal without suffix.
     const auto *Int = cast<IntegerLiteral>(Node->getCookedLiteral());
-    OS << Int->getValue().toString(10, /*isSigned*/false);
+    OS << toString(Int->getValue(), 10, /*isSigned*/false);
     break;
   }
   case UserDefinedLiteral::LOK_Floating: {

diff  --git a/clang/lib/AST/TemplateBase.cpp b/clang/lib/AST/TemplateBase.cpp
index 7be72cb2c0cb2..f44230d1bd03d 100644
--- a/clang/lib/AST/TemplateBase.cpp
+++ b/clang/lib/AST/TemplateBase.cpp
@@ -31,6 +31,7 @@
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/None.h"
 #include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/Compiler.h"
@@ -554,7 +555,7 @@ static const T &DiagTemplateArg(const T &DB, const 
TemplateArgument &Arg) {
     return DB << "nullptr";
 
   case TemplateArgument::Integral:
-    return DB << Arg.getAsIntegral().toString(10);
+    return DB << toString(Arg.getAsIntegral(), 10);
 
   case TemplateArgument::Template:
     return DB << Arg.getAsTemplate();

diff  --git a/clang/lib/AST/TextNodeDumper.cpp 
b/clang/lib/AST/TextNodeDumper.cpp
index d35c249ba2dbe..38e01fc66408c 100644
--- a/clang/lib/AST/TextNodeDumper.cpp
+++ b/clang/lib/AST/TextNodeDumper.cpp
@@ -21,6 +21,7 @@
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/Specifiers.h"
 #include "clang/Basic/TypeTraits.h"
+#include "llvm/ADT/StringExtras.h"
 
 #include <algorithm>
 #include <utility>
@@ -1035,7 +1036,7 @@ void TextNodeDumper::VisitCharacterLiteral(const 
CharacterLiteral *Node) {
 void TextNodeDumper::VisitIntegerLiteral(const IntegerLiteral *Node) {
   bool isSigned = Node->getType()->isSignedIntegerType();
   ColorScope Color(OS, ShowColors, ValueColor);
-  OS << " " << Node->getValue().toString(10, isSigned);
+  OS << " " << toString(Node->getValue(), 10, isSigned);
 }
 
 void TextNodeDumper::VisitFixedPointLiteral(const FixedPointLiteral *Node) {

diff  --git a/clang/lib/Analysis/ThreadSafetyCommon.cpp 
b/clang/lib/Analysis/ThreadSafetyCommon.cpp
index 0c5d1857cc2bd..e6b4a05501e2d 100644
--- a/clang/lib/Analysis/ThreadSafetyCommon.cpp
+++ b/clang/lib/Analysis/ThreadSafetyCommon.cpp
@@ -26,6 +26,7 @@
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/OperatorKinds.h"
 #include "clang/Basic/Specifiers.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Casting.h"
 #include <algorithm>
@@ -40,7 +41,7 @@ using namespace threadSafety;
 std::string threadSafety::getSourceLiteralString(const Expr *CE) {
   switch (CE->getStmtClass()) {
     case Stmt::IntegerLiteralClass:
-      return cast<IntegerLiteral>(CE)->getValue().toString(10, true);
+      return toString(cast<IntegerLiteral>(CE)->getValue(), 10, true);
     case Stmt::StringLiteralClass: {
       std::string ret("\"");
       ret += cast<StringLiteral>(CE)->getString();

diff  --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 1b30d44937f3e..37da763d8763c 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -9441,7 +9441,7 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned 
BuiltinID,
 
     llvm::APSInt Value = Result.Val.getInt();
     LLVMContext &Context = CGM.getLLVMContext();
-    std::string Reg = Value == 31 ? "sp" : "x" + Value.toString(10);
+    std::string Reg = Value == 31 ? "sp" : "x" + toString(Value, 10);
 
     llvm::Metadata *Ops[] = {llvm::MDString::get(Context, Reg)};
     llvm::MDNode *RegName = llvm::MDNode::get(Context, Ops);

diff  --git a/clang/lib/CodeGen/CodeGenModule.cpp 
b/clang/lib/CodeGen/CodeGenModule.cpp
index c3a4b1ba6b3d6..369c4b6ccef93 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -206,7 +206,7 @@ CodeGenModule::CodeGenModule(ASTContext &C, const 
HeaderSearchOptions &HSO,
     // created with -funique-internal-linakge-symbols and the tools can strip 
or
     // keep the prefix as needed.
     ModuleNameHash = (Twine(".__uniq.") +
-        Twine(IntHash.toString(/* Radix = */ 10, /* Signed = */false))).str();
+        Twine(toString(IntHash, /* Radix = */ 10, /* Signed = */false))).str();
   }
 }
 

diff  --git a/clang/lib/Frontend/CompilerInvocation.cpp 
b/clang/lib/Frontend/CompilerInvocation.cpp
index 24f899836ccf2..54904443958ac 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -4581,7 +4581,7 @@ std::string CompilerInvocation::getModuleHash() const {
   if (!SanHash.empty())
     code = hash_combine(code, SanHash.Mask);
 
-  return llvm::APInt(64, code).toString(36, /*Signed=*/false);
+  return toString(llvm::APInt(64, code), 36, /*Signed=*/false);
 }
 
 void CompilerInvocation::generateCC1CommandLine(

diff  --git a/clang/lib/Frontend/InitPreprocessor.cpp 
b/clang/lib/Frontend/InitPreprocessor.cpp
index e03f831c8becb..af1196f131925 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -168,7 +168,7 @@ static void DefineTypeSize(const Twine &MacroName, unsigned 
TypeWidth,
                            MacroBuilder &Builder) {
   llvm::APInt MaxVal = isSigned ? llvm::APInt::getSignedMaxValue(TypeWidth)
                                 : llvm::APInt::getMaxValue(TypeWidth);
-  Builder.defineMacro(MacroName, MaxVal.toString(10, isSigned) + ValSuffix);
+  Builder.defineMacro(MacroName, toString(MaxVal, 10, isSigned) + ValSuffix);
 }
 
 /// DefineTypeSize - An overloaded helper that uses TargetInfo to determine

diff  --git a/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp 
b/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp
index 34658caca6b32..fd54bcbf7c353 100644
--- a/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp
+++ b/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp
@@ -3674,8 +3674,7 @@ bool RewriteModernObjC::RewriteObjCFieldDeclType(QualType 
&Type,
       Result += " {\n";
       for (const auto *EC : ED->enumerators()) {
         Result += "\t"; Result += EC->getName(); Result += " = ";
-        llvm::APSInt Val = EC->getInitVal();
-        Result += Val.toString(10);
+        Result += toString(EC->getInitVal(), 10);
         Result += ",\n";
       }
       Result += "\t} ";

diff  --git a/clang/lib/Lex/PPExpressions.cpp b/clang/lib/Lex/PPExpressions.cpp
index 8537b31b9dc95..cab4bab630dc9 100644
--- a/clang/lib/Lex/PPExpressions.cpp
+++ b/clang/lib/Lex/PPExpressions.cpp
@@ -666,13 +666,13 @@ static bool EvaluateDirectiveSubExpr(PPValue &LHS, 
unsigned MinPrec,
       if (ValueLive && Res.isUnsigned()) {
         if (!LHS.isUnsigned() && LHS.Val.isNegative())
           PP.Diag(OpLoc, diag::warn_pp_convert_to_positive) << 0
-            << LHS.Val.toString(10, true) + " to " +
-               LHS.Val.toString(10, false)
+            << toString(LHS.Val, 10, true) + " to " +
+               toString(LHS.Val, 10, false)
             << LHS.getRange() << RHS.getRange();
         if (!RHS.isUnsigned() && RHS.Val.isNegative())
           PP.Diag(OpLoc, diag::warn_pp_convert_to_positive) << 1
-            << RHS.Val.toString(10, true) + " to " +
-               RHS.Val.toString(10, false)
+            << toString(RHS.Val, 10, true) + " to " +
+               toString(RHS.Val, 10, false)
             << LHS.getRange() << RHS.getRange();
       }
       LHS.Val.setIsUnsigned(Res.isUnsigned());

diff  --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp
index 480b61f1afe50..1e2113b58f814 100644
--- a/clang/lib/Sema/SemaCast.cpp
+++ b/clang/lib/Sema/SemaCast.cpp
@@ -2917,7 +2917,7 @@ void CastOperation::CheckCStyleCast() {
         }
         Self.Diag(OpRange.getBegin(),
                   diag::err_opencl_cast_non_zero_to_event_t)
-                  << CastInt.toString(10) << SrcExpr.get()->getSourceRange();
+                  << toString(CastInt, 10) << SrcExpr.get()->getSourceRange();
         SrcExpr = ExprError();
         return;
       }

diff  --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 86c888548077e..91498293d60e2 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -253,7 +253,7 @@ static bool SemaBuiltinAlignment(Sema &S, CallExpr 
*TheCall, unsigned ID) {
     }
     if (llvm::APSInt::compareValues(AlignValue, MaxValue) > 0) {
       S.Diag(AlignOp->getExprLoc(), diag::err_alignment_too_big)
-          << MaxValue.toString(10);
+          << toString(MaxValue, 10);
       return true;
     }
     if (!AlignValue.isPowerOf2()) {
@@ -772,8 +772,8 @@ void Sema::checkFortifiedBuiltinMemoryFunction(FunctionDecl 
*FD,
 
   DiagRuntimeBehavior(TheCall->getBeginLoc(), TheCall,
                       PDiag(DiagID)
-                          << FunctionName << ObjectSize.toString(/*Radix=*/10)
-                          << UsedSize.getValue().toString(/*Radix=*/10));
+                          << FunctionName << toString(ObjectSize, /*Radix=*/10)
+                          << toString(UsedSize.getValue(), /*Radix=*/10));
 }
 
 static bool SemaBuiltinSEHScopeCheck(Sema &SemaRef, CallExpr *TheCall,
@@ -6620,13 +6620,13 @@ bool Sema::SemaBuiltinConstantArgRange(CallExpr 
*TheCall, int ArgNum,
   if (Result.getSExtValue() < Low || Result.getSExtValue() > High) {
     if (RangeIsError)
       return Diag(TheCall->getBeginLoc(), diag::err_argument_invalid_range)
-             << Result.toString(10) << Low << High << Arg->getSourceRange();
+             << toString(Result, 10) << Low << High << Arg->getSourceRange();
     else
       // Defer the warning until we know if the code will be emitted so that
       // dead code can ignore this.
       DiagRuntimeBehavior(TheCall->getBeginLoc(), TheCall,
                           PDiag(diag::warn_argument_invalid_range)
-                              << Result.toString(10) << Low << High
+                              << toString(Result, 10) << Low << High
                               << Arg->getSourceRange());
   }
 
@@ -11743,8 +11743,8 @@ static bool AnalyzeBitFieldAssignment(Sema &S, 
FieldDecl *Bitfield, Expr *Init,
   if (FieldWidth == 1 && Value == 1)
     return false;
 
-  std::string PrettyValue = Value.toString(10);
-  std::string PrettyTrunc = TruncatedValue.toString(10);
+  std::string PrettyValue = toString(Value, 10);
+  std::string PrettyTrunc = toString(TruncatedValue, 10);
 
   S.Diag(InitLoc, diag::warn_impcast_bitfield_precision_constant)
     << PrettyValue << PrettyTrunc << OriginalInit->getType()
@@ -11980,7 +11980,7 @@ static std::string PrettyPrintInRange(const 
llvm::APSInt &Value,
   llvm::APSInt ValueInRange = Value;
   ValueInRange.setIsSigned(!Range.NonNegative);
   ValueInRange = ValueInRange.trunc(Range.Width);
-  return ValueInRange.toString(10);
+  return toString(ValueInRange, 10);
 }
 
 static bool IsImplicitBoolFloatConversion(Sema &S, Expr *Ex, bool ToBool) {
@@ -12296,7 +12296,7 @@ static void CheckImplicitConversion(Sema &S, Expr *E, 
QualType T,
         adornObjCBoolConversionDiagWithTernaryFixit(
             S, E,
             S.Diag(CC, diag::warn_impcast_constant_value_to_objc_bool)
-                << Result.Val.getInt().toString(10));
+                << toString(Result.Val.getInt(), 10));
       }
       return;
     }
@@ -12480,7 +12480,7 @@ static void CheckImplicitConversion(Sema &S, Expr *E, 
QualType T,
         if (Overflowed) {
           S.DiagRuntimeBehavior(E->getExprLoc(), E,
                                 S.PDiag(diag::warn_impcast_fixed_point_range)
-                                    << Value.toString(/*Radix=*/10) << T
+                                    << toString(Value, /*Radix=*/10) << T
                                     << E->getSourceRange()
                                     << clang::SourceRange(CC));
           return;
@@ -12520,7 +12520,8 @@ static void CheckImplicitConversion(Sema &S, Expr *E, 
QualType T,
                 llvm::APFloat::rmNearestTiesToEven);
 
         if (ConversionStatus != llvm::APFloat::opOK) {
-          std::string PrettySourceValue = SourceInt->toString(10);
+          SmallString<32> PrettySourceValue;
+          SourceInt->toString(PrettySourceValue, 10);
           SmallString<32> PrettyTargetValue;
           TargetFloatValue.toString(PrettyTargetValue, TargetPrecision);
 
@@ -12579,7 +12580,7 @@ static void CheckImplicitConversion(Sema &S, Expr *E, 
QualType T,
       if (S.SourceMgr.isInSystemMacro(CC))
         return;
 
-      std::string PrettySourceValue = Value.toString(10);
+      std::string PrettySourceValue = toString(Value, 10);
       std::string PrettyTargetValue = PrettyPrintInRange(Value, TargetRange);
 
       S.DiagRuntimeBehavior(
@@ -12625,7 +12626,7 @@ static void CheckImplicitConversion(Sema &S, Expr *E, 
QualType T,
         !S.SourceMgr.isInSystemMacro(CC)) {
       llvm::APSInt Value = Result.Val.getInt();
       if (isSameWidthConstantConversion(S, E, T, CC)) {
-        std::string PrettySourceValue = Value.toString(10);
+        std::string PrettySourceValue = toString(Value, 10);
         std::string PrettyTargetValue = PrettyPrintInRange(Value, TargetRange);
 
         S.DiagRuntimeBehavior(
@@ -14623,8 +14624,8 @@ void Sema::CheckArrayAccess(const Expr *BaseExpr, const 
Expr *IndexExpr,
       DiagID = diag::warn_array_index_exceeds_bounds;
 
     DiagRuntimeBehavior(BaseExpr->getBeginLoc(), BaseExpr,
-                        PDiag(DiagID) << index.toString(10, true)
-                                      << size.toString(10, true)
+                        PDiag(DiagID) << toString(index, 10, true)
+                                      << toString(size, 10, true)
                                       << (unsigned)size.getLimitedValue(~0U)
                                       << IndexExpr->getSourceRange());
   } else {
@@ -14635,7 +14636,7 @@ void Sema::CheckArrayAccess(const Expr *BaseExpr, const 
Expr *IndexExpr,
     }
 
     DiagRuntimeBehavior(BaseExpr->getBeginLoc(), BaseExpr,
-                        PDiag(DiagID) << index.toString(10, true)
+                        PDiag(DiagID) << toString(index, 10, true)
                                       << IndexExpr->getSourceRange());
   }
 

diff  --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index b67776b5348dc..552534824588e 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -25,6 +25,8 @@
 #include "clang/Basic/OperatorPrecedence.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/StringExtras.h"
+
 using namespace clang;
 using namespace sema;
 
@@ -573,9 +575,9 @@ static void 
diagnoseWellFormedUnsatisfiedConstraintExpr(Sema &S,
           S.Diag(SubstExpr->getBeginLoc(),
                  diag::note_atomic_constraint_evaluated_to_false_elaborated)
               << (int)First << SubstExpr
-              << SimplifiedLHS.Val.getInt().toString(10)
+              << toString(SimplifiedLHS.Val.getInt(), 10)
               << BinaryOperator::getOpcodeStr(BO->getOpcode())
-              << SimplifiedRHS.Val.getInt().toString(10);
+              << toString(SimplifiedRHS.Val.getInt(), 10);
           return;
         }
       }

diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 263edbb8add5f..0075464552321 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -6135,7 +6135,7 @@ bool Sema::tryToFixVariablyModifiedVarType(TypeSourceInfo 
*&TInfo,
   if (SizeIsNegative)
     Diag(Loc, diag::err_typecheck_negative_array_size);
   else if (Oversized.getBoolValue())
-    Diag(Loc, diag::err_array_too_large) << Oversized.toString(10);
+    Diag(Loc, diag::err_array_too_large) << toString(Oversized, 10);
   else if (FailedFoldDiagID)
     Diag(Loc, FailedFoldDiagID);
   return false;
@@ -6255,7 +6255,7 @@ Sema::CheckTypedefForVariablyModifiedType(Scope *S, 
TypedefNameDecl *NewTD) {
           Diag(NewTD->getLocation(), diag::err_vla_decl_in_file_scope);
         else if (Oversized.getBoolValue())
           Diag(NewTD->getLocation(), diag::err_array_too_large)
-            << Oversized.toString(10);
+            << toString(Oversized, 10);
         else
           Diag(NewTD->getLocation(), diag::err_vm_decl_in_file_scope);
         NewTD->setInvalidDecl();
@@ -16669,16 +16669,16 @@ ExprResult Sema::VerifyBitField(SourceLocation 
FieldLoc,
   if (Value.isSigned() && Value.isNegative()) {
     if (FieldName)
       return Diag(FieldLoc, diag::err_bitfield_has_negative_width)
-               << FieldName << Value.toString(10);
+               << FieldName << toString(Value, 10);
     return Diag(FieldLoc, diag::err_anon_bitfield_has_negative_width)
-      << Value.toString(10);
+      << toString(Value, 10);
   }
 
   // The size of the bit-field must not exceed our maximum permitted object
   // size.
   if (Value.getActiveBits() > ConstantArrayType::getMaxSizeBits(Context)) {
     return Diag(FieldLoc, diag::err_bitfield_too_wide)
-           << !FieldName << FieldName << Value.toString(10);
+           << !FieldName << FieldName << toString(Value, 10);
   }
 
   if (!FieldTy->isDependentType()) {
@@ -16698,11 +16698,11 @@ ExprResult Sema::VerifyBitField(SourceLocation 
FieldLoc,
           CStdConstraintViolation ? TypeWidth : TypeStorageSize;
       if (FieldName)
         return Diag(FieldLoc, diag::err_bitfield_width_exceeds_type_width)
-               << FieldName << Value.toString(10)
+               << FieldName << toString(Value, 10)
                << !CStdConstraintViolation << DiagWidth;
 
       return Diag(FieldLoc, diag::err_anon_bitfield_width_exceeds_type_width)
-             << Value.toString(10) << !CStdConstraintViolation
+             << toString(Value, 10) << !CStdConstraintViolation
              << DiagWidth;
     }
 
@@ -16711,7 +16711,7 @@ ExprResult Sema::VerifyBitField(SourceLocation FieldLoc,
     // 'bool'.
     if (BitfieldIsOverwide && !FieldTy->isBooleanType() && FieldName) {
       Diag(FieldLoc, diag::warn_bitfield_width_exceeds_type_width)
-          << FieldName << Value.toString(10)
+          << FieldName << toString(Value, 10)
           << (unsigned)TypeWidth;
     }
   }
@@ -17823,7 +17823,7 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl 
*Enum,
           // Complain if the value is not representable in an int.
           if (!isRepresentableIntegerValue(Context, EnumVal, Context.IntTy))
             Diag(IdLoc, diag::ext_enum_value_not_int)
-              << EnumVal.toString(10) << Val->getSourceRange()
+              << toString(EnumVal, 10) << Val->getSourceRange()
               << (EnumVal.isUnsigned() || EnumVal.isNonNegative());
           else if (!Context.hasSameType(Val->getType(), Context.IntTy)) {
             // Force the type of the expression to 'int'.
@@ -17881,11 +17881,11 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl 
*Enum,
           if (Enum->isFixed())
             // When the underlying type is fixed, this is ill-formed.
             Diag(IdLoc, diag::err_enumerator_wrapped)
-              << EnumVal.toString(10)
+              << toString(EnumVal, 10)
               << EltTy;
           else
             Diag(IdLoc, diag::ext_enumerator_increment_too_large)
-              << EnumVal.toString(10);
+              << toString(EnumVal, 10);
         } else {
           EltTy = T;
         }
@@ -17909,7 +17909,7 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl 
*Enum,
                  !isRepresentableIntegerValue(Context, EnumVal, EltTy)) {
         // Enforce C99 6.7.2.2p2 even when we compute the next value.
         Diag(IdLoc, diag::ext_enum_value_not_int)
-          << EnumVal.toString(10) << 1;
+          << toString(EnumVal, 10) << 1;
       }
     }
   }
@@ -18163,14 +18163,14 @@ static void CheckForDuplicateEnumValues(Sema &S, 
ArrayRef<Decl *> Elements,
     // Emit warning for one enum constant.
     auto *FirstECD = Vec->front();
     S.Diag(FirstECD->getLocation(), diag::warn_duplicate_enum_values)
-      << FirstECD << FirstECD->getInitVal().toString(10)
+      << FirstECD << toString(FirstECD->getInitVal(), 10)
       << FirstECD->getSourceRange();
 
     // Emit one note for each of the remaining enum constants with
     // the same value.
     for (auto *ECD : llvm::make_range(Vec->begin() + 1, Vec->end()))
       S.Diag(ECD->getLocation(), diag::note_duplicate_element)
-        << ECD << ECD->getInitVal().toString(10)
+        << ECD << toString(ECD->getInitVal(), 10)
         << ECD->getSourceRange();
   }
 }

diff  --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 4d75c817f51bb..2448636bdd52d 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -229,7 +229,7 @@ static bool checkUInt32Argument(Sema &S, const AttrInfo 
&AI, const Expr *Expr,
 
   if (!I->isIntN(32)) {
     S.Diag(Expr->getExprLoc(), diag::err_ice_too_large)
-        << I->toString(10, false) << 32 << /* Unsigned */ 1;
+        << toString(*I, 10, false) << 32 << /* Unsigned */ 1;
     return false;
   }
 
@@ -257,7 +257,7 @@ static bool checkPositiveIntArgument(Sema &S, const 
AttrInfo &AI, const Expr *Ex
     llvm::APSInt I(32); // for toString
     I = UVal;
     S.Diag(Expr->getExprLoc(), diag::err_ice_too_large)
-        << I.toString(10, false) << 32 << /* Unsigned */ 0;
+        << toString(I, 10, false) << 32 << /* Unsigned */ 0;
     return false;
   }
 
@@ -4990,7 +4990,7 @@ static Expr *makeLaunchBoundsArgExpr(Sema &S, Expr *E,
   // Make sure we can fit it in 32 bits.
   if (!I->isIntN(32)) {
     S.Diag(E->getExprLoc(), diag::err_ice_too_large)
-        << I->toString(10, false) << 32 << /* Unsigned */ 1;
+        << toString(*I, 10, false) << 32 << /* Unsigned */ 1;
     return nullptr;
   }
   if (*I < 0)

diff  --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index b0c0ff75f34f4..fd2d93e490c92 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -908,8 +908,8 @@ static bool checkSimpleDecomposition(
   if ((int64_t)Bindings.size() != NumElems) {
     S.Diag(Src->getLocation(), diag::err_decomp_decl_wrong_number_bindings)
         << DecompType << (unsigned)Bindings.size()
-        << (unsigned)NumElems.getLimitedValue(UINT_MAX) << 
NumElems.toString(10)
-        << (NumElems < Bindings.size());
+        << (unsigned)NumElems.getLimitedValue(UINT_MAX)
+        << toString(NumElems, 10) << (NumElems < Bindings.size());
     return true;
   }
 
@@ -1164,7 +1164,7 @@ static bool checkTupleLikeDecomposition(Sema &S,
     S.Diag(Src->getLocation(), diag::err_decomp_decl_wrong_number_bindings)
         << DecompType << (unsigned)Bindings.size()
         << (unsigned)TupleSize.getLimitedValue(UINT_MAX)
-        << TupleSize.toString(10) << (TupleSize < Bindings.size());
+        << toString(TupleSize, 10) << (TupleSize < Bindings.size());
     return true;
   }
 

diff  --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 0431c43a58290..b643356412574 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -47,8 +47,10 @@
 #include "clang/Sema/SemaInternal.h"
 #include "clang/Sema/Template.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/ConvertUTF.h"
 #include "llvm/Support/SaveAndRestore.h"
+
 using namespace clang;
 using namespace sema;
 using llvm::RoundingMode;
@@ -3671,7 +3673,7 @@ bool Sema::CheckLoopHintExpr(Expr *E, SourceLocation Loc) 
{
   bool ValueIsPositive = ValueAPS.isStrictlyPositive();
   if (!ValueIsPositive || ValueAPS.getActiveBits() > 31) {
     Diag(E->getExprLoc(), diag::err_pragma_loop_invalid_argument_value)
-        << ValueAPS.toString(10) << ValueIsPositive;
+        << toString(ValueAPS, 10) << ValueIsPositive;
     return true;
   }
 
@@ -5058,7 +5060,7 @@ ExprResult Sema::ActOnOMPArraySectionExpr(Expr *Base, 
SourceLocation LBLoc,
       llvm::APSInt LengthValue = Result.Val.getInt();
       if (LengthValue.isNegative()) {
         Diag(Length->getExprLoc(), diag::err_omp_section_length_negative)
-            << LengthValue.toString(/*Radix=*/10, /*Signed=*/true)
+            << toString(LengthValue, /*Radix=*/10, /*Signed=*/true)
             << Length->getSourceRange();
         return ExprError();
       }
@@ -5082,7 +5084,7 @@ ExprResult Sema::ActOnOMPArraySectionExpr(Expr *Base, 
SourceLocation LBLoc,
       llvm::APSInt StrideValue = Result.Val.getInt();
       if (!StrideValue.isStrictlyPositive()) {
         Diag(Stride->getExprLoc(), diag::err_omp_section_stride_non_positive)
-            << StrideValue.toString(/*Radix=*/10, /*Signed=*/true)
+            << toString(StrideValue, /*Radix=*/10, /*Signed=*/true)
             << Stride->getSourceRange();
         return ExprError();
       }
@@ -5161,7 +5163,7 @@ ExprResult Sema::ActOnOMPArrayShapingExpr(Expr *Base, 
SourceLocation LParenLoc,
         llvm::APSInt Value = EvResult.Val.getInt();
         if (!Value.isStrictlyPositive()) {
           Diag(Dim->getExprLoc(), diag::err_omp_shaping_dimension_not_positive)
-              << Value.toString(/*Radix=*/10, /*Signed=*/true)
+              << toString(Value, /*Radix=*/10, /*Signed=*/true)
               << Dim->getSourceRange();
           ErrorFound = true;
           continue;
@@ -12319,7 +12321,8 @@ static void diagnoseXorMisusedAsPow(Sema &S, const 
ExprResult &XorLHS,
       RHSStrRef.find('\'') != StringRef::npos)
     return;
 
-  bool SuggestXor = S.getLangOpts().CPlusPlus || 
S.getPreprocessor().isMacroDefined("xor");
+  bool SuggestXor =
+      S.getLangOpts().CPlusPlus || S.getPreprocessor().isMacroDefined("xor");
   const llvm::APInt XorValue = LeftSideValue ^ RightSideValue;
   int64_t RightSideIntValue = RightSideValue.getSExtValue();
   if (LeftSideValue == 2 && RightSideIntValue >= 0) {
@@ -12330,27 +12333,30 @@ static void diagnoseXorMisusedAsPow(Sema &S, const 
ExprResult &XorLHS,
     if (Overflow) {
       if (RightSideIntValue < 64)
         S.Diag(Loc, diag::warn_xor_used_as_pow_base)
-            << ExprStr << XorValue.toString(10, true) << ("1LL << " + RHSStr)
+            << ExprStr << toString(XorValue, 10, true) << ("1LL << " + RHSStr)
             << FixItHint::CreateReplacement(ExprRange, "1LL << " + RHSStr);
       else if (RightSideIntValue == 64)
-        S.Diag(Loc, diag::warn_xor_used_as_pow) << ExprStr << 
XorValue.toString(10, true);
+        S.Diag(Loc, diag::warn_xor_used_as_pow)
+            << ExprStr << toString(XorValue, 10, true);
       else
         return;
     } else {
       S.Diag(Loc, diag::warn_xor_used_as_pow_base_extra)
-          << ExprStr << XorValue.toString(10, true) << SuggestedExpr
-          << PowValue.toString(10, true)
+          << ExprStr << toString(XorValue, 10, true) << SuggestedExpr
+          << toString(PowValue, 10, true)
           << FixItHint::CreateReplacement(
                  ExprRange, (RightSideIntValue == 0) ? "1" : SuggestedExpr);
     }
 
-    S.Diag(Loc, diag::note_xor_used_as_pow_silence) << ("0x2 ^ " + RHSStr) << 
SuggestXor;
+    S.Diag(Loc, diag::note_xor_used_as_pow_silence)
+        << ("0x2 ^ " + RHSStr) << SuggestXor;
   } else if (LeftSideValue == 10) {
     std::string SuggestedValue = "1e" + std::to_string(RightSideIntValue);
     S.Diag(Loc, diag::warn_xor_used_as_pow_base)
-        << ExprStr << XorValue.toString(10, true) << SuggestedValue
+        << ExprStr << toString(XorValue, 10, true) << SuggestedValue
         << FixItHint::CreateReplacement(ExprRange, SuggestedValue);
-    S.Diag(Loc, diag::note_xor_used_as_pow_silence) << ("0xA ^ " + RHSStr) << 
SuggestXor;
+    S.Diag(Loc, diag::note_xor_used_as_pow_silence)
+        << ("0xA ^ " + RHSStr) << SuggestXor;
   }
 }
 

diff  --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 2f02cb41212ca..81a2e0cb775d0 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -2143,7 +2143,7 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
           if (ActiveSizeBits > ConstantArrayType::getMaxSizeBits(Context))
             return ExprError(
                 Diag((*ArraySize)->getBeginLoc(), diag::err_array_too_large)
-                << Value->toString(10) << (*ArraySize)->getSourceRange());
+                << toString(*Value, 10) << (*ArraySize)->getSourceRange());
         }
 
         KnownArraySize = Value->getZExtValue();

diff  --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 26d681b1340d8..f916299e4f560 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -2873,7 +2873,7 @@ InitListChecker::CheckDesignatedInitializer(const 
InitializedEntity &Entity,
       if (!VerifyOnly)
         SemaRef.Diag(IndexExpr->getBeginLoc(),
                      diag::err_array_designator_too_large)
-            << DesignatedEndIndex.toString(10) << MaxElements.toString(10)
+            << toString(DesignatedEndIndex, 10) << toString(MaxElements, 10)
             << IndexExpr->getSourceRange();
       ++Index;
       return true;
@@ -3167,7 +3167,7 @@ CheckArrayDesignatorExpr(Sema &S, Expr *Index, 
llvm::APSInt &Value) {
 
   if (Value.isSigned() && Value.isNegative())
     return S.Diag(Loc, diag::err_array_designator_negative)
-      << Value.toString(10) << Index->getSourceRange();
+           << toString(Value, 10) << Index->getSourceRange();
 
   Value.setIsUnsigned(true);
   return Result;
@@ -3236,7 +3236,7 @@ ExprResult Sema::ActOnDesignatedInitializer(Designation 
&Desig,
 
         if (!StartDependent && !EndDependent && EndValue < StartValue) {
           Diag(D.getEllipsisLoc(), diag::err_array_designator_empty_range)
-            << StartValue.toString(10) << EndValue.toString(10)
+            << toString(StartValue, 10) << toString(EndValue, 10)
             << StartIndex->getSourceRange() << EndIndex->getSourceRange();
           Invalid = true;
         } else {

diff  --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 2ec487130d30e..a67f0910bd07a 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -9965,14 +9965,14 @@ StmtResult Sema::ActOnOpenMPCriticalDirective(
       Diag(StartLoc, diag::err_omp_critical_with_hint);
       if (HintLoc.isValid())
         Diag(HintLoc, diag::note_omp_critical_hint_here)
-            << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false);
+            << 0 << toString(Hint, /*Radix=*/10, /*Signed=*/false);
       else
         Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
       if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
         Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here)
             << 1
-            << C->getHint()->EvaluateKnownConstInt(Context).toString(
-                   /*Radix=*/10, /*Signed=*/false);
+            << toString(C->getHint()->EvaluateKnownConstInt(Context),
+                        /*Radix=*/10, /*Signed=*/false);
       } else {
         Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
       }

diff  --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index da87d01de8e89..8bb2e0e8c8633 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -1106,8 +1106,8 @@ static void checkCaseValue(Sema &S, SourceLocation Loc, 
const llvm::APSInt &Val,
     // type versus "switch expression cannot have this value". Use proper
     // IntRange checking rather than just looking at the unpromoted type here.
     if (ConvVal != Val)
-      S.Diag(Loc, diag::warn_case_value_overflow) << Val.toString(10)
-                                                  << ConvVal.toString(10);
+      S.Diag(Loc, diag::warn_case_value_overflow) << toString(Val, 10)
+                                                  << toString(ConvVal, 10);
   }
 }
 
@@ -1432,7 +1432,7 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, 
Stmt *Switch,
         if (OverlapStmt) {
           // If we have a duplicate, report it.
           Diag(CR->getLHS()->getBeginLoc(), diag::err_duplicate_case)
-              << OverlapVal.toString(10);
+              << toString(OverlapVal, 10);
           Diag(OverlapStmt->getLHS()->getBeginLoc(),
                diag::note_duplicate_case_prev);
           // FIXME: We really want to remove the bogus case stmt from the
@@ -1448,7 +1448,7 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, 
Stmt *Switch,
       // TODO: it would be nice if we printed enums as enums, chars as
       // chars, etc.
       Diag(CondExpr->getExprLoc(), diag::warn_missing_case_for_condition)
-        << ConstantCondValue.toString(10)
+        << toString(ConstantCondValue, 10)
         << CondExpr->getSourceRange();
     }
 

diff  --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp
index 479de3e494163..243d0b921cd7e 100644
--- a/clang/lib/Sema/SemaStmtAsm.cpp
+++ b/clang/lib/Sema/SemaStmtAsm.cpp
@@ -405,7 +405,7 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, 
bool IsSimple,
             if (!Info.isValidAsmImmediate(IntResult))
               return StmtError(Diag(InputExpr->getBeginLoc(),
                                     diag::err_invalid_asm_value_for_constraint)
-                               << IntResult.toString(10)
+                               << toString(IntResult, 10)
                                << Info.getConstraintStr()
                                << InputExpr->getSourceRange());
         }

diff  --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 6f9d5dc2bc308..1753881983241 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -7202,10 +7202,10 @@ ExprResult 
Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
       Value.setIsSigned(IntegerType->isSignedIntegerOrEnumerationType());
 
       // Complain if an unsigned parameter received a negative value.
-      if (IntegerType->isUnsignedIntegerOrEnumerationType()
-               && (OldValue.isSigned() && OldValue.isNegative())) {
+      if (IntegerType->isUnsignedIntegerOrEnumerationType() &&
+          (OldValue.isSigned() && OldValue.isNegative())) {
         Diag(Arg->getBeginLoc(), diag::warn_template_arg_negative)
-            << OldValue.toString(10) << Value.toString(10) << Param->getType()
+            << toString(OldValue, 10) << toString(Value, 10) << 
Param->getType()
             << Arg->getSourceRange();
         Diag(Param->getLocation(), diag::note_template_param_here);
       }
@@ -7220,7 +7220,7 @@ ExprResult 
Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
         RequiredBits = OldValue.getMinSignedBits();
       if (RequiredBits > AllowedBits) {
         Diag(Arg->getBeginLoc(), diag::warn_template_arg_too_large)
-            << OldValue.toString(10) << Value.toString(10) << Param->getType()
+            << toString(OldValue, 10) << toString(Value, 10) << 
Param->getType()
             << Arg->getSourceRange();
         Diag(Param->getLocation(), diag::note_template_param_here);
       }

diff  --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 5f1d3ec7f8afc..4c5e6512419d1 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -2498,7 +2498,7 @@ QualType Sema::BuildArrayType(QualType T, 
ArrayType::ArraySizeModifier ASM,
               : ConstVal.getActiveBits();
       if (ActiveSizeBits > ConstantArrayType::getMaxSizeBits(Context)) {
         Diag(ArraySize->getBeginLoc(), diag::err_array_too_large)
-            << ConstVal.toString(10) << ArraySize->getSourceRange();
+            << toString(ConstVal, 10) << ArraySize->getSourceRange();
         return QualType();
       }
 

diff  --git a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp 
b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
index e54b9c13b9355..1088565d1a23d 100644
--- a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
+++ b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
@@ -20,6 +20,7 @@
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/ImmutableSet.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/raw_ostream.h"
 #include <algorithm>
@@ -493,7 +494,7 @@ RangeSet RangeSet::Factory::deletePoint(RangeSet From,
 }
 
 void Range::dump(raw_ostream &OS) const {
-  OS << '[' << From().toString(10) << ", " << To().toString(10) << ']';
+  OS << '[' << toString(From(), 10) << ", " << toString(To(), 10) << ']';
 }
 
 void RangeSet::dump(raw_ostream &OS) const {

diff  --git a/clang/unittests/StaticAnalyzer/RangeSetTest.cpp 
b/clang/unittests/StaticAnalyzer/RangeSetTest.cpp
index 6d9d70277d9d3..dc222e0b08065 100644
--- a/clang/unittests/StaticAnalyzer/RangeSetTest.cpp
+++ b/clang/unittests/StaticAnalyzer/RangeSetTest.cpp
@@ -28,7 +28,7 @@ template <class RangeOrSet> static std::string toString(const 
RangeOrSet &Obj) {
   return SS.str();
 }
 LLVM_ATTRIBUTE_UNUSED static std::string toString(const llvm::APSInt &Point) {
-  return Point.toString(10);
+  return toString(Point, 10);
 }
 // We need it here for better fail diagnostics from gtest.
 LLVM_ATTRIBUTE_UNUSED static std::ostream &operator<<(std::ostream &OS,

diff  --git 
a/clang/unittests/Tooling/RecursiveASTVisitorTestPostOrderVisitor.cpp 
b/clang/unittests/Tooling/RecursiveASTVisitorTestPostOrderVisitor.cpp
index 9fd075ee605b5..8ac0604c09110 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTestPostOrderVisitor.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTestPostOrderVisitor.cpp
@@ -41,7 +41,7 @@ class RecordingVisitor : public TestVisitor<RecordingVisitor> 
{
   }
 
   bool VisitIntegerLiteral(IntegerLiteral *Lit) {
-    VisitedNodes.push_back(Lit->getValue().toString(10, false));
+    VisitedNodes.push_back(toString(Lit->getValue(), 10, false));
     return true;
   }
 

diff  --git 
a/clang/unittests/Tooling/RecursiveASTVisitorTests/CallbacksCommon.h 
b/clang/unittests/Tooling/RecursiveASTVisitorTests/CallbacksCommon.h
index a95143000837d..92e30c2d46e5f 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/CallbacksCommon.h
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/CallbacksCommon.h
@@ -39,7 +39,7 @@ class RecordingVisitorBase : public TestVisitor<Derived> {
   std::string stmtToString(Stmt *S) {
     StringRef ClassName = S->getStmtClassName();
     if (IntegerLiteral *IL = dyn_cast<IntegerLiteral>(S)) {
-      return (ClassName + "(" + IL->getValue().toString(10, false) + 
")").str();
+      return (ClassName + "(" + toString(IL->getValue(), 10, false) + 
")").str();
     }
     if (UnaryOperator *UO = dyn_cast<UnaryOperator>(S)) {
       return (ClassName + "(" + UnaryOperator::getOpcodeStr(UO->getOpcode()) +

diff  --git a/llvm/include/llvm/ADT/APInt.h b/llvm/include/llvm/ADT/APInt.h
index f184fb5e1dfe4..5b1db209caf50 100644
--- a/llvm/include/llvm/ADT/APInt.h
+++ b/llvm/include/llvm/ADT/APInt.h
@@ -20,7 +20,6 @@
 #include <cassert>
 #include <climits>
 #include <cstring>
-#include <string>
 
 namespace llvm {
 class FoldingSetNodeID;
@@ -1753,13 +1752,6 @@ class LLVM_NODISCARD APInt {
     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/llvm/include/llvm/ADT/APSInt.h b/llvm/include/llvm/ADT/APSInt.h
index f7af13205e3e9..1509d472f1311 100644
--- a/llvm/include/llvm/ADT/APSInt.h
+++ b/llvm/include/llvm/ADT/APSInt.h
@@ -82,11 +82,6 @@ class LLVM_NODISCARD APSInt : public APInt {
   void toString(SmallVectorImpl<char> &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/llvm/include/llvm/ADT/StringExtras.h 
b/llvm/include/llvm/ADT/StringExtras.h
index 68e89508cba91..6bda25b85313e 100644
--- a/llvm/include/llvm/ADT/StringExtras.h
+++ b/llvm/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<uint64_t>(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/llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp 
b/llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp
index 558bb6fd78c2c..a7f0d5fde1284 100644
--- a/llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp
+++ b/llvm/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/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp 
b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index c7fa1d6772716..ace475dbe86f9 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/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/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp
index 462d19d2e7ba4..a8a950f09747b 100644
--- a/llvm/lib/Support/APInt.cpp
+++ b/llvm/lib/Support/APInt.cpp
@@ -2281,14 +2281,6 @@ void APInt::toString(SmallVectorImpl<char> &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/llvm/lib/Target/X86/X86MCInstLower.cpp 
b/llvm/lib/Target/X86/X86MCInstLower.cpp
index 89fa3ae3a3f42..7d916f917d5e0 100644
--- a/llvm/lib/Target/X86/X86MCInstLower.cpp
+++ b/llvm/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<ConstantFP>(C)) {
-        CS << "0x" << CF->getValueAPF().bitcastToAPInt().toString(16, false);
+        CS << "0x" << toString(CF->getValueAPF().bitcastToAPInt(), 16, false);
         OutStreamer.AddComment(CS.str());
       }
     }

diff  --git a/llvm/lib/Transforms/IPO/OpenMPOpt.cpp 
b/llvm/lib/Transforms/IPO/OpenMPOpt.cpp
index 061deaf62c958..87440d7557f02 100644
--- a/llvm/lib/Transforms/IPO/OpenMPOpt.cpp
+++ b/llvm/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/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp 
b/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp
index 7ceef254e608d..4a4c2d6f3c5c6 100644
--- a/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp
+++ b/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp
@@ -255,7 +255,7 @@ template <> struct ScalarTraits<exegesis::RegisterValue> {
                      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/llvm/tools/llvm-pdbutil/MinimalSymbolDumper.cpp 
b/llvm/tools/llvm-pdbutil/MinimalSymbolDumper.cpp
index 787785c34b788..17bc53de24703 100644
--- a/llvm/tools/llvm-pdbutil/MinimalSymbolDumper.cpp
+++ b/llvm/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/llvm/tools/llvm-pdbutil/MinimalTypeDumper.cpp 
b/llvm/tools/llvm-pdbutil/MinimalTypeDumper.cpp
index 8e46a97272d58..08006e9c62d42 100644
--- a/llvm/tools/llvm-pdbutil/MinimalTypeDumper.cpp
+++ b/llvm/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/llvm/unittests/ADT/APIntTest.cpp 
b/llvm/unittests/ADT/APIntTest.cpp
index ef5423e332e1c..947d9598bac2f 100644
--- a/llvm/unittests/ADT/APIntTest.cpp
+++ b/llvm/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/llvm/unittests/ADT/StringExtrasTest.cpp 
b/llvm/unittests/ADT/StringExtrasTest.cpp
index 9816273524fac..206392c3a2716 100644
--- a/llvm/unittests/ADT/StringExtrasTest.cpp
+++ b/llvm/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


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to