[clang] [llvm] [llvm][clang] Move RewriterBuffer to ADT. (PR #99770)

Jacques Pienaar via cfe-commits cfe-commits at lists.llvm.org
Sat Jul 20 10:06:12 PDT 2024


https://github.com/jpienaar created https://github.com/llvm/llvm-project/pull/99770

These classes are not specific to clang and useful for other rewriter tools (flagged in previous review).

>From 451a4c61066c4a433bc100ebc511dc6447f83ab0 Mon Sep 17 00:00:00 2001
From: Jacques Pienaar <jpienaar at google.com>
Date: Sat, 20 Jul 2024 16:25:14 +0000
Subject: [PATCH] [llvm][clang] Move RewriterBuffer to ADT.

These classes are not specific to clang and useful for other rewriter tools.
---
 clang/include/clang/Rewrite/Core/DeltaTree.h  |  50 --
 .../include/clang/Rewrite/Core/HTMLRewrite.h  |  11 +-
 .../include/clang/Rewrite/Core/RewriteRope.h  | 223 --------
 clang/include/clang/Rewrite/Core/Rewriter.h   |  19 +-
 clang/lib/ARCMigrate/ARCMT.cpp                |   2 +-
 clang/lib/ARCMigrate/ObjCMT.cpp               |   1 +
 clang/lib/Frontend/Rewrite/FixItRewriter.cpp  |   3 +-
 clang/lib/Frontend/Rewrite/HTMLPrint.cpp      |   2 +
 clang/lib/Frontend/Rewrite/RewriteMacros.cpp  |   4 +-
 .../Frontend/Rewrite/RewriteModernObjC.cpp    |   3 +-
 clang/lib/Frontend/Rewrite/RewriteObjC.cpp    |   1 +
 clang/lib/Rewrite/CMakeLists.txt              |   2 -
 clang/lib/Rewrite/HTMLRewrite.cpp             |   1 +
 clang/lib/Rewrite/Rewriter.cpp                | 109 +---
 .../StaticAnalyzer/Core/HTMLDiagnostics.cpp   |   2 +
 clang/lib/Tooling/Core/Replacement.cpp        |   2 +-
 clang/unittests/Rewrite/CMakeLists.txt        |   1 -
 llvm/include/llvm/ADT/DeltaTree.h             |  50 ++
 .../include/llvm/ADT}/RewriteBuffer.h         |  40 +-
 llvm/include/llvm/ADT/RewriteRope.h           | 223 ++++++++
 llvm/lib/Support/CMakeLists.txt               |   3 +
 .../lib/Support}/DeltaTree.cpp                | 265 +++++----
 llvm/lib/Support/RewriteBuffer.cpp            | 107 ++++
 .../lib/Support}/RewriteRope.cpp              | 507 +++++++++---------
 llvm/unittests/ADT/CMakeLists.txt             |   1 +
 .../unittests/ADT}/RewriteBufferTest.cpp      |   5 +-
 26 files changed, 825 insertions(+), 812 deletions(-)
 delete mode 100644 clang/include/clang/Rewrite/Core/DeltaTree.h
 delete mode 100644 clang/include/clang/Rewrite/Core/RewriteRope.h
 create mode 100644 llvm/include/llvm/ADT/DeltaTree.h
 rename {clang/include/clang/Rewrite/Core => llvm/include/llvm/ADT}/RewriteBuffer.h (82%)
 create mode 100644 llvm/include/llvm/ADT/RewriteRope.h
 rename {clang/lib/Rewrite => llvm/lib/Support}/DeltaTree.cpp (68%)
 create mode 100644 llvm/lib/Support/RewriteBuffer.cpp
 rename {clang/lib/Rewrite => llvm/lib/Support}/RewriteRope.cpp (63%)
 rename {clang/unittests/Rewrite => llvm/unittests/ADT}/RewriteBufferTest.cpp (96%)

diff --git a/clang/include/clang/Rewrite/Core/DeltaTree.h b/clang/include/clang/Rewrite/Core/DeltaTree.h
deleted file mode 100644
index e566c92aaff91..0000000000000
--- a/clang/include/clang/Rewrite/Core/DeltaTree.h
+++ /dev/null
@@ -1,50 +0,0 @@
-//===- DeltaTree.h - B-Tree for Rewrite Delta tracking ----------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the DeltaTree class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_REWRITE_CORE_DELTATREE_H
-#define LLVM_CLANG_REWRITE_CORE_DELTATREE_H
-
-namespace clang {
-
-  /// DeltaTree - a multiway search tree (BTree) structure with some fancy
-  /// features.  B-Trees are generally more memory and cache efficient than
-  /// binary trees, because they store multiple keys/values in each node.  This
-  /// implements a key/value mapping from index to delta, and allows fast lookup
-  /// on index.  However, an added (important) bonus is that it can also
-  /// efficiently tell us the full accumulated delta for a specific file offset
-  /// as well, without traversing the whole tree.
-  class DeltaTree {
-    void *Root;    // "DeltaTreeNode *"
-
-  public:
-    DeltaTree();
-
-    // Note: Currently we only support copying when the RHS is empty.
-    DeltaTree(const DeltaTree &RHS);
-
-    DeltaTree &operator=(const DeltaTree &) = delete;
-    ~DeltaTree();
-
-    /// getDeltaAt - Return the accumulated delta at the specified file offset.
-    /// This includes all insertions or delections that occurred *before* the
-    /// specified file index.
-    int getDeltaAt(unsigned FileIndex) const;
-
-    /// AddDelta - When a change is made that shifts around the text buffer,
-    /// this method is used to record that info.  It inserts a delta of 'Delta'
-    /// into the current DeltaTree at offset FileIndex.
-    void AddDelta(unsigned FileIndex, int Delta);
-  };
-
-} // namespace clang
-
-#endif // LLVM_CLANG_REWRITE_CORE_DELTATREE_H
diff --git a/clang/include/clang/Rewrite/Core/HTMLRewrite.h b/clang/include/clang/Rewrite/Core/HTMLRewrite.h
index eecf589632746..9edb514d566b9 100644
--- a/clang/include/clang/Rewrite/Core/HTMLRewrite.h
+++ b/clang/include/clang/Rewrite/Core/HTMLRewrite.h
@@ -17,10 +17,13 @@
 #include "clang/Basic/SourceLocation.h"
 #include <string>
 
+namespace llvm {
+class RewriteBuffer;
+} // namespace llvm
+
 namespace clang {
 
 class Rewriter;
-class RewriteBuffer;
 class Preprocessor;
 
 namespace html {
@@ -53,9 +56,9 @@ namespace html {
 
   /// HighlightRange - This is the same as the above method, but takes
   /// decomposed file locations.
-  void HighlightRange(RewriteBuffer &RB, unsigned B, unsigned E,
-                      const char *BufferStart,
-                      const char *StartTag, const char *EndTag);
+  void HighlightRange(llvm::RewriteBuffer &RB, unsigned B, unsigned E,
+                      const char *BufferStart, const char *StartTag,
+                      const char *EndTag);
 
   /// EscapeText - HTMLize a specified file so that special characters are
   /// are translated so that they are not interpreted as HTML tags.
diff --git a/clang/include/clang/Rewrite/Core/RewriteRope.h b/clang/include/clang/Rewrite/Core/RewriteRope.h
deleted file mode 100644
index 73e66e111f574..0000000000000
--- a/clang/include/clang/Rewrite/Core/RewriteRope.h
+++ /dev/null
@@ -1,223 +0,0 @@
-//===- RewriteRope.h - Rope specialized for rewriter ------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-//  This file defines the RewriteRope class, which is a powerful string class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_REWRITE_CORE_REWRITEROPE_H
-#define LLVM_CLANG_REWRITE_CORE_REWRITEROPE_H
-
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/StringRef.h"
-#include <cassert>
-#include <cstddef>
-#include <iterator>
-#include <utility>
-
-namespace clang {
-
-  //===--------------------------------------------------------------------===//
-  // RopeRefCountString Class
-  //===--------------------------------------------------------------------===//
-
-  /// RopeRefCountString - This struct is allocated with 'new char[]' from the
-  /// heap, and represents a reference counted chunk of string data.  When its
-  /// ref count drops to zero, it is delete[]'d.  This is primarily managed
-  /// through the RopePiece class below.
-  struct RopeRefCountString {
-    unsigned RefCount;
-    char Data[1];  //  Variable sized.
-
-    void Retain() { ++RefCount; }
-
-    void Release() {
-      assert(RefCount > 0 && "Reference count is already zero.");
-      if (--RefCount == 0)
-        delete [] (char*)this;
-    }
-  };
-
-  //===--------------------------------------------------------------------===//
-  // RopePiece Class
-  //===--------------------------------------------------------------------===//
-
-  /// RopePiece - This class represents a view into a RopeRefCountString object.
-  /// This allows references to string data to be efficiently chopped up and
-  /// moved around without having to push around the string data itself.
-  ///
-  /// For example, we could have a 1M RopePiece and want to insert something
-  /// into the middle of it.  To do this, we split it into two RopePiece objects
-  /// that both refer to the same underlying RopeRefCountString (just with
-  /// different offsets) which is a nice constant time operation.
-  struct RopePiece {
-    llvm::IntrusiveRefCntPtr<RopeRefCountString> StrData;
-    unsigned StartOffs = 0;
-    unsigned EndOffs = 0;
-
-    RopePiece() = default;
-    RopePiece(llvm::IntrusiveRefCntPtr<RopeRefCountString> Str, unsigned Start,
-              unsigned End)
-        : StrData(std::move(Str)), StartOffs(Start), EndOffs(End) {}
-
-    const char &operator[](unsigned Offset) const {
-      return StrData->Data[Offset+StartOffs];
-    }
-    char &operator[](unsigned Offset) {
-      return StrData->Data[Offset+StartOffs];
-    }
-
-    unsigned size() const { return EndOffs-StartOffs; }
-  };
-
-  //===--------------------------------------------------------------------===//
-  // RopePieceBTreeIterator Class
-  //===--------------------------------------------------------------------===//
-
-  /// RopePieceBTreeIterator - This class provides read-only forward iteration
-  /// over bytes that are in a RopePieceBTree.  This first iterates over bytes
-  /// in a RopePiece, then iterates over RopePiece's in a RopePieceBTreeLeaf,
-  /// then iterates over RopePieceBTreeLeaf's in a RopePieceBTree.
-  class RopePieceBTreeIterator {
-    /// CurNode - The current B+Tree node that we are inspecting.
-    const void /*RopePieceBTreeLeaf*/ *CurNode = nullptr;
-
-    /// CurPiece - The current RopePiece in the B+Tree node that we're
-    /// inspecting.
-    const RopePiece *CurPiece = nullptr;
-
-    /// CurChar - The current byte in the RopePiece we are pointing to.
-    unsigned CurChar = 0;
-
-  public:
-    using iterator_category = std::forward_iterator_tag;
-    using value_type = const char;
-    using difference_type = std::ptrdiff_t;
-    using pointer = value_type *;
-    using reference = value_type &;
-
-    RopePieceBTreeIterator() = default;
-    RopePieceBTreeIterator(const void /*RopePieceBTreeNode*/ *N);
-
-    char operator*() const {
-      return (*CurPiece)[CurChar];
-    }
-
-    bool operator==(const RopePieceBTreeIterator &RHS) const {
-      return CurPiece == RHS.CurPiece && CurChar == RHS.CurChar;
-    }
-    bool operator!=(const RopePieceBTreeIterator &RHS) const {
-      return !operator==(RHS);
-    }
-
-    RopePieceBTreeIterator& operator++() {   // Preincrement
-      if (CurChar+1 < CurPiece->size())
-        ++CurChar;
-      else
-        MoveToNextPiece();
-      return *this;
-    }
-
-    RopePieceBTreeIterator operator++(int) { // Postincrement
-      RopePieceBTreeIterator tmp = *this; ++*this; return tmp;
-    }
-
-    llvm::StringRef piece() const {
-      return llvm::StringRef(&(*CurPiece)[0], CurPiece->size());
-    }
-
-    void MoveToNextPiece();
-  };
-
-  //===--------------------------------------------------------------------===//
-  // RopePieceBTree Class
-  //===--------------------------------------------------------------------===//
-
-  class RopePieceBTree {
-    void /*RopePieceBTreeNode*/ *Root;
-
-  public:
-    RopePieceBTree();
-    RopePieceBTree(const RopePieceBTree &RHS);
-    RopePieceBTree &operator=(const RopePieceBTree &) = delete;
-    ~RopePieceBTree();
-
-    using iterator = RopePieceBTreeIterator;
-
-    iterator begin() const { return iterator(Root); }
-    iterator end() const { return iterator(); }
-    unsigned size() const;
-    unsigned empty() const { return size() == 0; }
-
-    void clear();
-
-    void insert(unsigned Offset, const RopePiece &R);
-
-    void erase(unsigned Offset, unsigned NumBytes);
-  };
-
-  //===--------------------------------------------------------------------===//
-  // RewriteRope Class
-  //===--------------------------------------------------------------------===//
-
-/// RewriteRope - A powerful string class.  This class supports extremely
-/// efficient insertions and deletions into the middle of it, even for
-/// ridiculously long strings.
-class RewriteRope {
-  RopePieceBTree Chunks;
-
-  /// We allocate space for string data out of a buffer of size AllocChunkSize.
-  /// This keeps track of how much space is left.
-  llvm::IntrusiveRefCntPtr<RopeRefCountString> AllocBuffer;
-  enum { AllocChunkSize = 4080 };
-  unsigned AllocOffs = AllocChunkSize;
-
-public:
-  RewriteRope() = default;
-  RewriteRope(const RewriteRope &RHS) : Chunks(RHS.Chunks) {}
-
-  // The copy assignment operator is defined as deleted pending further
-  // motivation.
-  RewriteRope &operator=(const RewriteRope &) = delete;
-
-  using iterator = RopePieceBTree::iterator;
-  using const_iterator = RopePieceBTree::iterator;
-
-  iterator begin() const { return Chunks.begin(); }
-  iterator end() const { return Chunks.end(); }
-  unsigned size() const { return Chunks.size(); }
-
-  void clear() {
-    Chunks.clear();
-  }
-
-  void assign(const char *Start, const char *End) {
-    clear();
-    if (Start != End)
-      Chunks.insert(0, MakeRopeString(Start, End));
-  }
-
-  void insert(unsigned Offset, const char *Start, const char *End) {
-    assert(Offset <= size() && "Invalid position to insert!");
-    if (Start == End) return;
-    Chunks.insert(Offset, MakeRopeString(Start, End));
-  }
-
-  void erase(unsigned Offset, unsigned NumBytes) {
-    assert(Offset+NumBytes <= size() && "Invalid region to erase!");
-    if (NumBytes == 0) return;
-    Chunks.erase(Offset, NumBytes);
-  }
-
-private:
-  RopePiece MakeRopeString(const char *Start, const char *End);
-};
-
-} // namespace clang
-
-#endif // LLVM_CLANG_REWRITE_CORE_REWRITEROPE_H
diff --git a/clang/include/clang/Rewrite/Core/Rewriter.h b/clang/include/clang/Rewrite/Core/Rewriter.h
index c89015e405582..4e96f6fcca919 100644
--- a/clang/include/clang/Rewrite/Core/Rewriter.h
+++ b/clang/include/clang/Rewrite/Core/Rewriter.h
@@ -16,7 +16,7 @@
 
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/SourceLocation.h"
-#include "clang/Rewrite/Core/RewriteBuffer.h"
+#include "llvm/ADT/RewriteBuffer.h"
 #include "llvm/ADT/StringRef.h"
 #include <map>
 #include <string>
@@ -32,7 +32,7 @@ class SourceManager;
 class Rewriter {
   SourceManager *SourceMgr = nullptr;
   const LangOptions *LangOpts = nullptr;
-  std::map<FileID, RewriteBuffer> RewriteBuffers;
+  std::map<FileID, llvm::RewriteBuffer> RewriteBuffers;
 
 public:
   struct RewriteOptions {
@@ -49,7 +49,7 @@ class Rewriter {
     ///
     /// FIXME: This sometimes corrupts the file's rewrite buffer due to
     /// incorrect indexing in the implementation (see the FIXME in
-    /// clang::RewriteBuffer::RemoveText).  Moreover, it's inefficient because
+    /// llvm::RewriteBuffer::RemoveText).  Moreover, it's inefficient because
     /// it must scan the buffer from the beginning to find the start of the
     /// line.  When feasible, it's better for the caller to check for a blank
     /// line and then, if found, expand the removal range to include it.
@@ -62,8 +62,9 @@ class Rewriter {
     RewriteOptions() {}
   };
 
-  using buffer_iterator = std::map<FileID, RewriteBuffer>::iterator;
-  using const_buffer_iterator = std::map<FileID, RewriteBuffer>::const_iterator;
+  using buffer_iterator = std::map<FileID, llvm::RewriteBuffer>::iterator;
+  using const_buffer_iterator =
+      std::map<FileID, llvm::RewriteBuffer>::const_iterator;
 
   explicit Rewriter() = default;
   explicit Rewriter(SourceManager &SM, const LangOptions &LO)
@@ -191,13 +192,13 @@ class Rewriter {
   /// buffer, and allows you to write on it directly.  This is useful if you
   /// want efficient low-level access to apis for scribbling on one specific
   /// FileID's buffer.
-  RewriteBuffer &getEditBuffer(FileID FID);
+  llvm::RewriteBuffer &getEditBuffer(FileID FID);
 
   /// getRewriteBufferFor - Return the rewrite buffer for the specified FileID.
   /// If no modification has been made to it, return null.
-  const RewriteBuffer *getRewriteBufferFor(FileID FID) const {
-    std::map<FileID, RewriteBuffer>::const_iterator I =
-      RewriteBuffers.find(FID);
+  const llvm::RewriteBuffer *getRewriteBufferFor(FileID FID) const {
+    std::map<FileID, llvm::RewriteBuffer>::const_iterator I =
+        RewriteBuffers.find(FID);
     return I == RewriteBuffers.end() ? nullptr : &I->second;
   }
 
diff --git a/clang/lib/ARCMigrate/ARCMT.cpp b/clang/lib/ARCMigrate/ARCMT.cpp
index 5835559bff6b7..1a8a200f2fc19 100644
--- a/clang/lib/ARCMigrate/ARCMT.cpp
+++ b/clang/lib/ARCMigrate/ARCMT.cpp
@@ -596,7 +596,7 @@ bool MigrationProcess::applyTransform(TransformFn trans,
   for (Rewriter::buffer_iterator
         I = rewriter.buffer_begin(), E = rewriter.buffer_end(); I != E; ++I) {
     FileID FID = I->first;
-    RewriteBuffer &buf = I->second;
+    llvm::RewriteBuffer &buf = I->second;
     OptionalFileEntryRef file =
         Ctx.getSourceManager().getFileEntryRefForID(FID);
     assert(file);
diff --git a/clang/lib/ARCMigrate/ObjCMT.cpp b/clang/lib/ARCMigrate/ObjCMT.cpp
index 4357c8e3f09a5..c1bc7c762088f 100644
--- a/clang/lib/ARCMigrate/ObjCMT.cpp
+++ b/clang/lib/ARCMigrate/ObjCMT.cpp
@@ -36,6 +36,7 @@
 using namespace clang;
 using namespace arcmt;
 using namespace ento;
+using llvm::RewriteBuffer;
 
 namespace {
 
diff --git a/clang/lib/Frontend/Rewrite/FixItRewriter.cpp b/clang/lib/Frontend/Rewrite/FixItRewriter.cpp
index 567bac576adb4..44dfaf20eae73 100644
--- a/clang/lib/Frontend/Rewrite/FixItRewriter.cpp
+++ b/clang/lib/Frontend/Rewrite/FixItRewriter.cpp
@@ -21,8 +21,8 @@
 #include "clang/Edit/Commit.h"
 #include "clang/Edit/EditsReceiver.h"
 #include "clang/Frontend/FrontendDiagnostic.h"
-#include "clang/Rewrite/Core/RewriteBuffer.h"
 #include "clang/Rewrite/Core/Rewriter.h"
+#include "llvm/ADT/RewriteBuffer.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/raw_ostream.h"
@@ -33,6 +33,7 @@
 #include <utility>
 
 using namespace clang;
+using llvm::RewriteBuffer;
 
 FixItRewriter::FixItRewriter(DiagnosticsEngine &Diags, SourceManager &SourceMgr,
                              const LangOptions &LangOpts,
diff --git a/clang/lib/Frontend/Rewrite/HTMLPrint.cpp b/clang/lib/Frontend/Rewrite/HTMLPrint.cpp
index 69baa8f591088..5cce193ed1c4f 100644
--- a/clang/lib/Frontend/Rewrite/HTMLPrint.cpp
+++ b/clang/lib/Frontend/Rewrite/HTMLPrint.cpp
@@ -20,8 +20,10 @@
 #include "clang/Rewrite/Core/HTMLRewrite.h"
 #include "clang/Rewrite/Core/Rewriter.h"
 #include "clang/Rewrite/Frontend/ASTConsumers.h"
+#include "llvm/ADT/RewriteBuffer.h"
 #include "llvm/Support/raw_ostream.h"
 using namespace clang;
+using llvm::RewriteBuffer;
 
 //===----------------------------------------------------------------------===//
 // Functional HTML pretty-printing.
diff --git a/clang/lib/Frontend/Rewrite/RewriteMacros.cpp b/clang/lib/Frontend/Rewrite/RewriteMacros.cpp
index 5701b271aff10..b533cabe97f5e 100644
--- a/clang/lib/Frontend/Rewrite/RewriteMacros.cpp
+++ b/clang/lib/Frontend/Rewrite/RewriteMacros.cpp
@@ -11,16 +11,18 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "clang/Rewrite/Frontend/Rewriters.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Rewrite/Core/Rewriter.h"
+#include "clang/Rewrite/Frontend/Rewriters.h"
+#include "llvm/ADT/RewriteBuffer.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
 #include <cstdio>
 #include <memory>
 
 using namespace clang;
+using llvm::RewriteBuffer;
 
 /// isSameToken - Return true if the two specified tokens start have the same
 /// content.
diff --git a/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp b/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp
index 3849e4040b53a..f618c536b5f3c 100644
--- a/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp
+++ b/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp
@@ -10,7 +10,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "clang/Rewrite/Frontend/ASTConsumers.h"
 #include "clang/AST/AST.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/Attr.h"
@@ -23,6 +22,7 @@
 #include "clang/Config/config.h"
 #include "clang/Lex/Lexer.h"
 #include "clang/Rewrite/Core/Rewriter.h"
+#include "clang/Rewrite/Frontend/ASTConsumers.h"
 #include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/SetVector.h"
 #include "llvm/ADT/SmallPtrSet.h"
@@ -34,6 +34,7 @@
 #if CLANG_ENABLE_OBJC_REWRITER
 
 using namespace clang;
+using llvm::RewriteBuffer;
 using llvm::utostr;
 
 namespace {
diff --git a/clang/lib/Frontend/Rewrite/RewriteObjC.cpp b/clang/lib/Frontend/Rewrite/RewriteObjC.cpp
index bf5176a2b6fb2..9db6ddbf0b890 100644
--- a/clang/lib/Frontend/Rewrite/RewriteObjC.cpp
+++ b/clang/lib/Frontend/Rewrite/RewriteObjC.cpp
@@ -32,6 +32,7 @@
 #if CLANG_ENABLE_OBJC_REWRITER
 
 using namespace clang;
+using llvm::RewriteBuffer;
 using llvm::utostr;
 
 namespace {
diff --git a/clang/lib/Rewrite/CMakeLists.txt b/clang/lib/Rewrite/CMakeLists.txt
index 16550b1b710ef..93ecb3c835260 100644
--- a/clang/lib/Rewrite/CMakeLists.txt
+++ b/clang/lib/Rewrite/CMakeLists.txt
@@ -3,9 +3,7 @@ set(LLVM_LINK_COMPONENTS
   )
 
 add_clang_library(clangRewrite
-  DeltaTree.cpp
   HTMLRewrite.cpp
-  RewriteRope.cpp
   Rewriter.cpp
   TokenRewriter.cpp
 
diff --git a/clang/lib/Rewrite/HTMLRewrite.cpp b/clang/lib/Rewrite/HTMLRewrite.cpp
index a96ca0764ae73..c75835df2c98e 100644
--- a/clang/lib/Rewrite/HTMLRewrite.cpp
+++ b/clang/lib/Rewrite/HTMLRewrite.cpp
@@ -16,6 +16,7 @@
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Lex/TokenConcatenation.h"
 #include "clang/Rewrite/Core/Rewriter.h"
+#include "llvm/ADT/RewriteBuffer.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/MemoryBuffer.h"
diff --git a/clang/lib/Rewrite/Rewriter.cpp b/clang/lib/Rewrite/Rewriter.cpp
index 0e6ae36506446..68cf797f97905 100644
--- a/clang/lib/Rewrite/Rewriter.cpp
+++ b/clang/lib/Rewrite/Rewriter.cpp
@@ -17,8 +17,8 @@
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Lex/Lexer.h"
-#include "clang/Rewrite/Core/RewriteBuffer.h"
-#include "clang/Rewrite/Core/RewriteRope.h"
+#include "llvm/ADT/RewriteBuffer.h"
+#include "llvm/ADT/RewriteRope.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Error.h"
@@ -29,113 +29,18 @@
 #include <utility>
 
 using namespace clang;
+using llvm::RewriteBuffer;
 
-raw_ostream &RewriteBuffer::write(raw_ostream &os) const {
-  // Walk RewriteRope chunks efficiently using MoveToNextPiece() instead of the
-  // character iterator.
-  for (RopePieceBTreeIterator I = begin(), E = end(); I != E;
-       I.MoveToNextPiece())
-    os << I.piece();
-  return os;
-}
+//===----------------------------------------------------------------------===//
+// Rewriter class
+//===----------------------------------------------------------------------===//
 
 /// Return true if this character is non-new-line whitespace:
 /// ' ', '\\t', '\\f', '\\v', '\\r'.
 static inline bool isWhitespaceExceptNL(unsigned char c) {
-  switch (c) {
-  case ' ':
-  case '\t':
-  case '\f':
-  case '\v':
-  case '\r':
-    return true;
-  default:
-    return false;
-  }
+  return c == ' ' || c == '\t' || c == '\f' || c == '\v' || c == '\r';
 }
 
-void RewriteBuffer::RemoveText(unsigned OrigOffset, unsigned Size,
-                               bool removeLineIfEmpty) {
-  // Nothing to remove, exit early.
-  if (Size == 0) return;
-
-  unsigned RealOffset = getMappedOffset(OrigOffset, true);
-  assert(RealOffset+Size <= Buffer.size() && "Invalid location");
-
-  // Remove the dead characters.
-  Buffer.erase(RealOffset, Size);
-
-  // Add a delta so that future changes are offset correctly.
-  AddReplaceDelta(OrigOffset, -Size);
-
-  if (removeLineIfEmpty) {
-    // Find the line that the remove occurred and if it is completely empty
-    // remove the line as well.
-
-    iterator curLineStart = begin();
-    unsigned curLineStartOffs = 0;
-    iterator posI = begin();
-    for (unsigned i = 0; i != RealOffset; ++i) {
-      if (*posI == '\n') {
-        curLineStart = posI;
-        ++curLineStart;
-        curLineStartOffs = i + 1;
-      }
-      ++posI;
-    }
-
-    unsigned lineSize = 0;
-    posI = curLineStart;
-    while (posI != end() && isWhitespaceExceptNL(*posI)) {
-      ++posI;
-      ++lineSize;
-    }
-    if (posI != end() && *posI == '\n') {
-      Buffer.erase(curLineStartOffs, lineSize + 1/* + '\n'*/);
-      // FIXME: Here, the offset of the start of the line is supposed to be
-      // expressed in terms of the original input not the "real" rewrite
-      // buffer.  How do we compute that reliably?  It might be tempting to use
-      // curLineStartOffs + OrigOffset - RealOffset, but that assumes the
-      // difference between the original and real offset is the same at the
-      // removed text and at the start of the line, but that's not true if
-      // edits were previously made earlier on the line.  This bug is also
-      // documented by a FIXME on the definition of
-      // clang::Rewriter::RewriteOptions::RemoveLineIfEmpty.  A reproducer for
-      // the implementation below is the test RemoveLineIfEmpty in
-      // clang/unittests/Rewrite/RewriteBufferTest.cpp.
-      AddReplaceDelta(curLineStartOffs, -(lineSize + 1/* + '\n'*/));
-    }
-  }
-}
-
-void RewriteBuffer::InsertText(unsigned OrigOffset, StringRef Str,
-                               bool InsertAfter) {
-  // Nothing to insert, exit early.
-  if (Str.empty()) return;
-
-  unsigned RealOffset = getMappedOffset(OrigOffset, InsertAfter);
-  Buffer.insert(RealOffset, Str.begin(), Str.end());
-
-  // Add a delta so that future changes are offset correctly.
-  AddInsertDelta(OrigOffset, Str.size());
-}
-
-/// ReplaceText - This method replaces a range of characters in the input
-/// buffer with a new string.  This is effectively a combined "remove+insert"
-/// operation.
-void RewriteBuffer::ReplaceText(unsigned OrigOffset, unsigned OrigLength,
-                                StringRef NewStr) {
-  unsigned RealOffset = getMappedOffset(OrigOffset, true);
-  Buffer.erase(RealOffset, OrigLength);
-  Buffer.insert(RealOffset, NewStr.begin(), NewStr.end());
-  if (OrigLength != NewStr.size())
-    AddReplaceDelta(OrigOffset, NewStr.size() - OrigLength);
-}
-
-//===----------------------------------------------------------------------===//
-// Rewriter class
-//===----------------------------------------------------------------------===//
-
 /// getRangeSize - Return the size in bytes of the specified range if they
 /// are in the same file.  If not, this returns -1.
 int Rewriter::getRangeSize(const CharSourceRange &Range,
diff --git a/clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp b/clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
index fb5030d373c2f..28d9de2973b01 100644
--- a/clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
+++ b/clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
@@ -27,6 +27,7 @@
 #include "clang/Rewrite/Core/Rewriter.h"
 #include "clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/RewriteBuffer.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/Sequence.h"
 #include "llvm/ADT/SmallString.h"
@@ -52,6 +53,7 @@
 
 using namespace clang;
 using namespace ento;
+using llvm::RewriteBuffer;
 
 //===----------------------------------------------------------------------===//
 // Boilerplate.
diff --git a/clang/lib/Tooling/Core/Replacement.cpp b/clang/lib/Tooling/Core/Replacement.cpp
index 269f17a6db4cf..9acf00263b5a8 100644
--- a/clang/lib/Tooling/Core/Replacement.cpp
+++ b/clang/lib/Tooling/Core/Replacement.cpp
@@ -19,9 +19,9 @@
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Lex/Lexer.h"
-#include "clang/Rewrite/Core/RewriteBuffer.h"
 #include "clang/Rewrite/Core/Rewriter.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/RewriteBuffer.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Error.h"
diff --git a/clang/unittests/Rewrite/CMakeLists.txt b/clang/unittests/Rewrite/CMakeLists.txt
index 6594d8cc5897f..3c5e2f8e5354b 100644
--- a/clang/unittests/Rewrite/CMakeLists.txt
+++ b/clang/unittests/Rewrite/CMakeLists.txt
@@ -3,7 +3,6 @@ set(LLVM_LINK_COMPONENTS
   )
 
 add_clang_unittest(RewriteTests
-  RewriteBufferTest.cpp
   RewriterTest.cpp
   )
 clang_target_link_libraries(RewriteTests
diff --git a/llvm/include/llvm/ADT/DeltaTree.h b/llvm/include/llvm/ADT/DeltaTree.h
new file mode 100644
index 0000000000000..5db9d74d9d529
--- /dev/null
+++ b/llvm/include/llvm/ADT/DeltaTree.h
@@ -0,0 +1,50 @@
+//===- DeltaTree.h - B-Tree for Rewrite Delta tracking ----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the DeltaTree class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_DELTATREE_H
+#define LLVM_ADT_DELTATREE_H
+
+namespace llvm {
+
+/// DeltaTree - a multiway search tree (BTree) structure with some fancy
+/// features.  B-Trees are generally more memory and cache efficient than
+/// binary trees, because they store multiple keys/values in each node.  This
+/// implements a key/value mapping from index to delta, and allows fast lookup
+/// on index.  However, an added (important) bonus is that it can also
+/// efficiently tell us the full accumulated delta for a specific file offset
+/// as well, without traversing the whole tree.
+class DeltaTree {
+  void *Root; // "DeltaTreeNode *"
+
+public:
+  DeltaTree();
+
+  // Note: Currently we only support copying when the RHS is empty.
+  DeltaTree(const DeltaTree &RHS);
+
+  DeltaTree &operator=(const DeltaTree &) = delete;
+  ~DeltaTree();
+
+  /// getDeltaAt - Return the accumulated delta at the specified file offset.
+  /// This includes all insertions or delections that occurred *before* the
+  /// specified file index.
+  int getDeltaAt(unsigned FileIndex) const;
+
+  /// AddDelta - When a change is made that shifts around the text buffer,
+  /// this method is used to record that info.  It inserts a delta of 'Delta'
+  /// into the current DeltaTree at offset FileIndex.
+  void AddDelta(unsigned FileIndex, int Delta);
+};
+
+} // namespace llvm
+
+#endif // LLVM_ADT_DELTATREE_H
diff --git a/clang/include/clang/Rewrite/Core/RewriteBuffer.h b/llvm/include/llvm/ADT/RewriteBuffer.h
similarity index 82%
rename from clang/include/clang/Rewrite/Core/RewriteBuffer.h
rename to llvm/include/llvm/ADT/RewriteBuffer.h
index b8f34174b7156..8197a06f882c1 100644
--- a/clang/include/clang/Rewrite/Core/RewriteBuffer.h
+++ b/llvm/include/llvm/ADT/RewriteBuffer.h
@@ -6,15 +6,20 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_CLANG_REWRITE_CORE_REWRITEBUFFER_H
-#define LLVM_CLANG_REWRITE_CORE_REWRITEBUFFER_H
+#ifndef LLVM_ADT_REWRITEBUFFER_H
+#define LLVM_ADT_REWRITEBUFFER_H
 
-#include "clang/Basic/LLVM.h"
-#include "clang/Rewrite/Core/DeltaTree.h"
-#include "clang/Rewrite/Core/RewriteRope.h"
+#include "llvm/ADT/DeltaTree.h"
+#include "llvm/ADT/RewriteRope.h"
 #include "llvm/ADT/StringRef.h"
 
 namespace clang {
+class Rewriter;
+} // namespace clang
+
+namespace llvm {
+
+class raw_ostream;
 
 /// RewriteBuffer - As code is rewritten, SourceBuffer's from the original
 /// input with modifications get a new RewriteBuffer associated with them.  The
@@ -23,7 +28,7 @@ namespace clang {
 /// RewriteBuffer.  For example, if text is inserted into the buffer, any
 /// locations after the insertion point have to be mapped.
 class RewriteBuffer {
-  friend class Rewriter;
+  friend class clang::Rewriter;
 
   /// Deltas - Keep track of all the deltas in the source code due to insertions
   /// and deletions.
@@ -43,9 +48,7 @@ class RewriteBuffer {
   void Initialize(const char *BufStart, const char *BufEnd) {
     Buffer.assign(BufStart, BufEnd);
   }
-  void Initialize(StringRef Input) {
-    Initialize(Input.begin(), Input.end());
-  }
+  void Initialize(StringRef Input) { Initialize(Input.begin(), Input.end()); }
 
   /// Write to \p Stream the result of applying all changes to the
   /// original buffer.
@@ -63,9 +66,7 @@ class RewriteBuffer {
   /// InsertText - Insert some text at the specified point, where the offset in
   /// the buffer is specified relative to the original SourceBuffer.  The
   /// text is inserted after the specified location.
-  void InsertText(unsigned OrigOffset, StringRef Str,
-                  bool InsertAfter = true);
-
+  void InsertText(unsigned OrigOffset, StringRef Str, bool InsertAfter = true);
 
   /// InsertTextBefore - Insert some text before the specified point, where the
   /// offset in the buffer is specified relative to the original
@@ -85,8 +86,7 @@ class RewriteBuffer {
   /// ReplaceText - This method replaces a range of characters in the input
   /// buffer with a new string.  This is effectively a combined "remove/insert"
   /// operation.
-  void ReplaceText(unsigned OrigOffset, unsigned OrigLength,
-                   StringRef NewStr);
+  void ReplaceText(unsigned OrigOffset, unsigned OrigLength, StringRef NewStr);
 
 private:
   /// getMappedOffset - Given an offset into the original SourceBuffer that this
@@ -95,23 +95,23 @@ class RewriteBuffer {
   /// position where text is inserted, the location returned will be after any
   /// inserted text at the position.
   unsigned getMappedOffset(unsigned OrigOffset,
-                           bool AfterInserts = false) const{
-    return Deltas.getDeltaAt(2*OrigOffset+AfterInserts)+OrigOffset;
+                           bool AfterInserts = false) const {
+    return Deltas.getDeltaAt(2 * OrigOffset + AfterInserts) + OrigOffset;
   }
 
   /// AddInsertDelta - When an insertion is made at a position, this
   /// method is used to record that information.
   void AddInsertDelta(unsigned OrigOffset, int Change) {
-    return Deltas.AddDelta(2*OrigOffset, Change);
+    return Deltas.AddDelta(2 * OrigOffset, Change);
   }
 
   /// AddReplaceDelta - When a replacement/deletion is made at a position, this
   /// method is used to record that information.
   void AddReplaceDelta(unsigned OrigOffset, int Change) {
-    return Deltas.AddDelta(2*OrigOffset+1, Change);
+    return Deltas.AddDelta(2 * OrigOffset + 1, Change);
   }
 };
 
-} // namespace clang
+} // namespace llvm
 
-#endif // LLVM_CLANG_REWRITE_CORE_REWRITEBUFFER_H
+#endif // LLVM_ADT_REWRITEBUFFER_H
diff --git a/llvm/include/llvm/ADT/RewriteRope.h b/llvm/include/llvm/ADT/RewriteRope.h
new file mode 100644
index 0000000000000..784f3c07eaa62
--- /dev/null
+++ b/llvm/include/llvm/ADT/RewriteRope.h
@@ -0,0 +1,223 @@
+//===- RewriteRope.h - Rope specialized for rewriter ------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the RewriteRope class, which is a powerful string class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_REWRITEROPE_H
+#define LLVM_ADT_REWRITEROPE_H
+
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/StringRef.h"
+#include <cassert>
+#include <cstddef>
+#include <iterator>
+#include <utility>
+
+namespace llvm {
+
+//===--------------------------------------------------------------------===//
+// RopeRefCountString Class
+//===--------------------------------------------------------------------===//
+
+/// RopeRefCountString - This struct is allocated with 'new char[]' from the
+/// heap, and represents a reference counted chunk of string data.  When its
+/// ref count drops to zero, it is delete[]'d.  This is primarily managed
+/// through the RopePiece class below.
+struct RopeRefCountString {
+  unsigned RefCount;
+  char Data[1]; //  Variable sized.
+
+  void Retain() { ++RefCount; }
+
+  void Release() {
+    assert(RefCount > 0 && "Reference count is already zero.");
+    if (--RefCount == 0)
+      delete[] (char *)this;
+  }
+};
+
+//===--------------------------------------------------------------------===//
+// RopePiece Class
+//===--------------------------------------------------------------------===//
+
+/// RopePiece - This class represents a view into a RopeRefCountString object.
+/// This allows references to string data to be efficiently chopped up and
+/// moved around without having to push around the string data itself.
+///
+/// For example, we could have a 1M RopePiece and want to insert something
+/// into the middle of it.  To do this, we split it into two RopePiece objects
+/// that both refer to the same underlying RopeRefCountString (just with
+/// different offsets) which is a nice constant time operation.
+struct RopePiece {
+  llvm::IntrusiveRefCntPtr<RopeRefCountString> StrData;
+  unsigned StartOffs = 0;
+  unsigned EndOffs = 0;
+
+  RopePiece() = default;
+  RopePiece(llvm::IntrusiveRefCntPtr<RopeRefCountString> Str, unsigned Start,
+            unsigned End)
+      : StrData(std::move(Str)), StartOffs(Start), EndOffs(End) {}
+
+  const char &operator[](unsigned Offset) const {
+    return StrData->Data[Offset + StartOffs];
+  }
+  char &operator[](unsigned Offset) {
+    return StrData->Data[Offset + StartOffs];
+  }
+
+  unsigned size() const { return EndOffs - StartOffs; }
+};
+
+//===--------------------------------------------------------------------===//
+// RopePieceBTreeIterator Class
+//===--------------------------------------------------------------------===//
+
+/// RopePieceBTreeIterator - This class provides read-only forward iteration
+/// over bytes that are in a RopePieceBTree.  This first iterates over bytes
+/// in a RopePiece, then iterates over RopePiece's in a RopePieceBTreeLeaf,
+/// then iterates over RopePieceBTreeLeaf's in a RopePieceBTree.
+class RopePieceBTreeIterator {
+  /// CurNode - The current B+Tree node that we are inspecting.
+  const void /*RopePieceBTreeLeaf*/ *CurNode = nullptr;
+
+  /// CurPiece - The current RopePiece in the B+Tree node that we're
+  /// inspecting.
+  const RopePiece *CurPiece = nullptr;
+
+  /// CurChar - The current byte in the RopePiece we are pointing to.
+  unsigned CurChar = 0;
+
+public:
+  using iterator_category = std::forward_iterator_tag;
+  using value_type = const char;
+  using difference_type = std::ptrdiff_t;
+  using pointer = value_type *;
+  using reference = value_type &;
+
+  RopePieceBTreeIterator() = default;
+  RopePieceBTreeIterator(const void /*RopePieceBTreeNode*/ *N);
+
+  char operator*() const { return (*CurPiece)[CurChar]; }
+
+  bool operator==(const RopePieceBTreeIterator &RHS) const {
+    return CurPiece == RHS.CurPiece && CurChar == RHS.CurChar;
+  }
+  bool operator!=(const RopePieceBTreeIterator &RHS) const {
+    return !operator==(RHS);
+  }
+
+  RopePieceBTreeIterator &operator++() { // Preincrement
+    if (CurChar + 1 < CurPiece->size())
+      ++CurChar;
+    else
+      MoveToNextPiece();
+    return *this;
+  }
+
+  RopePieceBTreeIterator operator++(int) { // Postincrement
+    RopePieceBTreeIterator tmp = *this;
+    ++*this;
+    return tmp;
+  }
+
+  llvm::StringRef piece() const {
+    return llvm::StringRef(&(*CurPiece)[0], CurPiece->size());
+  }
+
+  void MoveToNextPiece();
+};
+
+//===--------------------------------------------------------------------===//
+// RopePieceBTree Class
+//===--------------------------------------------------------------------===//
+
+class RopePieceBTree {
+  void /*RopePieceBTreeNode*/ *Root;
+
+public:
+  RopePieceBTree();
+  RopePieceBTree(const RopePieceBTree &RHS);
+  RopePieceBTree &operator=(const RopePieceBTree &) = delete;
+  ~RopePieceBTree();
+
+  using iterator = RopePieceBTreeIterator;
+
+  iterator begin() const { return iterator(Root); }
+  iterator end() const { return iterator(); }
+  unsigned size() const;
+  unsigned empty() const { return size() == 0; }
+
+  void clear();
+
+  void insert(unsigned Offset, const RopePiece &R);
+
+  void erase(unsigned Offset, unsigned NumBytes);
+};
+
+//===--------------------------------------------------------------------===//
+// RewriteRope Class
+//===--------------------------------------------------------------------===//
+
+/// RewriteRope - A powerful string class.  This class supports extremely
+/// efficient insertions and deletions into the middle of it, even for
+/// ridiculously long strings.
+class RewriteRope {
+  RopePieceBTree Chunks;
+
+  /// We allocate space for string data out of a buffer of size AllocChunkSize.
+  /// This keeps track of how much space is left.
+  llvm::IntrusiveRefCntPtr<RopeRefCountString> AllocBuffer;
+  enum { AllocChunkSize = 4080 };
+  unsigned AllocOffs = AllocChunkSize;
+
+public:
+  RewriteRope() = default;
+  RewriteRope(const RewriteRope &RHS) : Chunks(RHS.Chunks) {}
+
+  // The copy assignment operator is defined as deleted pending further
+  // motivation.
+  RewriteRope &operator=(const RewriteRope &) = delete;
+
+  using iterator = RopePieceBTree::iterator;
+  using const_iterator = RopePieceBTree::iterator;
+
+  iterator begin() const { return Chunks.begin(); }
+  iterator end() const { return Chunks.end(); }
+  unsigned size() const { return Chunks.size(); }
+
+  void clear() { Chunks.clear(); }
+
+  void assign(const char *Start, const char *End) {
+    clear();
+    if (Start != End)
+      Chunks.insert(0, MakeRopeString(Start, End));
+  }
+
+  void insert(unsigned Offset, const char *Start, const char *End) {
+    assert(Offset <= size() && "Invalid position to insert!");
+    if (Start == End)
+      return;
+    Chunks.insert(Offset, MakeRopeString(Start, End));
+  }
+
+  void erase(unsigned Offset, unsigned NumBytes) {
+    assert(Offset + NumBytes <= size() && "Invalid region to erase!");
+    if (NumBytes == 0)
+      return;
+    Chunks.erase(Offset, NumBytes);
+  }
+
+private:
+  RopePiece MakeRopeString(const char *Start, const char *End);
+};
+
+} // namespace llvm
+
+#endif // LLVM_ADT_REWRITEROPE_H
diff --git a/llvm/lib/Support/CMakeLists.txt b/llvm/lib/Support/CMakeLists.txt
index f653379e30334..a73ac54a01c5a 100644
--- a/llvm/lib/Support/CMakeLists.txt
+++ b/llvm/lib/Support/CMakeLists.txt
@@ -168,6 +168,7 @@ add_llvm_component_library(LLVMSupport
   Debug.cpp
   DebugCounter.cpp
   DeltaAlgorithm.cpp
+  DeltaTree.cpp
   DivisionByConstantInfo.cpp
   DAGDeltaAlgorithm.cpp
   DJB.cpp
@@ -216,6 +217,8 @@ add_llvm_component_library(LLVMSupport
   PrettyStackTrace.cpp
   RandomNumberGenerator.cpp
   Regex.cpp
+  RewriteBuffer.cpp
+  RewriteRope.cpp
   RISCVAttributes.cpp
   RISCVAttributeParser.cpp
   RISCVISAUtils.cpp
diff --git a/clang/lib/Rewrite/DeltaTree.cpp b/llvm/lib/Support/DeltaTree.cpp
similarity index 68%
rename from clang/lib/Rewrite/DeltaTree.cpp
rename to llvm/lib/Support/DeltaTree.cpp
index 61467f84928f2..2eb642ffd1df6 100644
--- a/clang/lib/Rewrite/DeltaTree.cpp
+++ b/llvm/lib/Support/DeltaTree.cpp
@@ -10,13 +10,12 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "clang/Rewrite/Core/DeltaTree.h"
-#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/DeltaTree.h"
 #include "llvm/Support/Casting.h"
 #include <cassert>
 #include <cstring>
 
-using namespace clang;
+using namespace llvm;
 
 /// The DeltaTree class is a multiway search tree (BTree) structure with some
 /// fancy features.  B-Trees are generally more memory and cache efficient
@@ -35,125 +34,125 @@ using namespace clang;
 
 namespace {
 
-  /// SourceDelta - As code in the original input buffer is added and deleted,
-  /// SourceDelta records are used to keep track of how the input SourceLocation
-  /// object is mapped into the output buffer.
-  struct SourceDelta {
-    unsigned FileLoc;
-    int Delta;
-
-    static SourceDelta get(unsigned Loc, int D) {
-      SourceDelta Delta;
-      Delta.FileLoc = Loc;
-      Delta.Delta = D;
-      return Delta;
-    }
+/// SourceDelta - As code in the original input buffer is added and deleted,
+/// SourceDelta records are used to keep track of how the input SourceLocation
+/// object is mapped into the output buffer.
+struct SourceDelta {
+  unsigned FileLoc;
+  int Delta;
+
+  static SourceDelta get(unsigned Loc, int D) {
+    SourceDelta Delta;
+    Delta.FileLoc = Loc;
+    Delta.Delta = D;
+    return Delta;
+  }
+};
+
+/// DeltaTreeNode - The common part of all nodes.
+///
+class DeltaTreeNode {
+public:
+  struct InsertResult {
+    DeltaTreeNode *LHS, *RHS;
+    SourceDelta Split;
   };
 
-  /// DeltaTreeNode - The common part of all nodes.
-  ///
-  class DeltaTreeNode {
-  public:
-    struct InsertResult {
-      DeltaTreeNode *LHS, *RHS;
-      SourceDelta Split;
-    };
-
-  private:
-    friend class DeltaTreeInteriorNode;
-
-    /// WidthFactor - This controls the number of K/V slots held in the BTree:
-    /// how wide it is.  Each level of the BTree is guaranteed to have at least
-    /// WidthFactor-1 K/V pairs (except the root) and may have at most
-    /// 2*WidthFactor-1 K/V pairs.
-    enum { WidthFactor = 8 };
-
-    /// Values - This tracks the SourceDelta's currently in this node.
-    SourceDelta Values[2*WidthFactor-1];
-
-    /// NumValuesUsed - This tracks the number of values this node currently
-    /// holds.
-    unsigned char NumValuesUsed = 0;
-
-    /// IsLeaf - This is true if this is a leaf of the btree.  If false, this is
-    /// an interior node, and is actually an instance of DeltaTreeInteriorNode.
-    bool IsLeaf;
-
-    /// FullDelta - This is the full delta of all the values in this node and
-    /// all children nodes.
-    int FullDelta = 0;
+private:
+  friend class DeltaTreeInteriorNode;
 
-  public:
-    DeltaTreeNode(bool isLeaf = true) : IsLeaf(isLeaf) {}
+  /// WidthFactor - This controls the number of K/V slots held in the BTree:
+  /// how wide it is.  Each level of the BTree is guaranteed to have at least
+  /// WidthFactor-1 K/V pairs (except the root) and may have at most
+  /// 2*WidthFactor-1 K/V pairs.
+  enum { WidthFactor = 8 };
 
-    bool isLeaf() const { return IsLeaf; }
-    int getFullDelta() const { return FullDelta; }
-    bool isFull() const { return NumValuesUsed == 2*WidthFactor-1; }
+  /// Values - This tracks the SourceDelta's currently in this node.
+  SourceDelta Values[2 * WidthFactor - 1];
 
-    unsigned getNumValuesUsed() const { return NumValuesUsed; }
+  /// NumValuesUsed - This tracks the number of values this node currently
+  /// holds.
+  unsigned char NumValuesUsed = 0;
 
-    const SourceDelta &getValue(unsigned i) const {
-      assert(i < NumValuesUsed && "Invalid value #");
-      return Values[i];
-    }
+  /// IsLeaf - This is true if this is a leaf of the btree.  If false, this is
+  /// an interior node, and is actually an instance of DeltaTreeInteriorNode.
+  bool IsLeaf;
 
-    SourceDelta &getValue(unsigned i) {
-      assert(i < NumValuesUsed && "Invalid value #");
-      return Values[i];
-    }
+  /// FullDelta - This is the full delta of all the values in this node and
+  /// all children nodes.
+  int FullDelta = 0;
 
-    /// DoInsertion - Do an insertion of the specified FileIndex/Delta pair into
-    /// this node.  If insertion is easy, do it and return false.  Otherwise,
-    /// split the node, populate InsertRes with info about the split, and return
-    /// true.
-    bool DoInsertion(unsigned FileIndex, int Delta, InsertResult *InsertRes);
+public:
+  DeltaTreeNode(bool isLeaf = true) : IsLeaf(isLeaf) {}
 
-    void DoSplit(InsertResult &InsertRes);
+  bool isLeaf() const { return IsLeaf; }
+  int getFullDelta() const { return FullDelta; }
+  bool isFull() const { return NumValuesUsed == 2 * WidthFactor - 1; }
 
+  unsigned getNumValuesUsed() const { return NumValuesUsed; }
 
-    /// RecomputeFullDeltaLocally - Recompute the FullDelta field by doing a
-    /// local walk over our contained deltas.
-    void RecomputeFullDeltaLocally();
+  const SourceDelta &getValue(unsigned i) const {
+    assert(i < NumValuesUsed && "Invalid value #");
+    return Values[i];
+  }
 
-    void Destroy();
-  };
+  SourceDelta &getValue(unsigned i) {
+    assert(i < NumValuesUsed && "Invalid value #");
+    return Values[i];
+  }
 
-  /// DeltaTreeInteriorNode - When isLeaf = false, a node has child pointers.
-  /// This class tracks them.
-  class DeltaTreeInteriorNode : public DeltaTreeNode {
-    friend class DeltaTreeNode;
+  /// DoInsertion - Do an insertion of the specified FileIndex/Delta pair into
+  /// this node.  If insertion is easy, do it and return false.  Otherwise,
+  /// split the node, populate InsertRes with info about the split, and return
+  /// true.
+  bool DoInsertion(unsigned FileIndex, int Delta, InsertResult *InsertRes);
 
-    DeltaTreeNode *Children[2*WidthFactor];
+  void DoSplit(InsertResult &InsertRes);
 
-    ~DeltaTreeInteriorNode() {
-      for (unsigned i = 0, e = NumValuesUsed+1; i != e; ++i)
-        Children[i]->Destroy();
-    }
+  /// RecomputeFullDeltaLocally - Recompute the FullDelta field by doing a
+  /// local walk over our contained deltas.
+  void RecomputeFullDeltaLocally();
 
-  public:
-    DeltaTreeInteriorNode() : DeltaTreeNode(false /*nonleaf*/) {}
+  void Destroy();
+};
 
-    DeltaTreeInteriorNode(const InsertResult &IR)
-        : DeltaTreeNode(false /*nonleaf*/) {
-      Children[0] = IR.LHS;
-      Children[1] = IR.RHS;
-      Values[0] = IR.Split;
-      FullDelta = IR.LHS->getFullDelta()+IR.RHS->getFullDelta()+IR.Split.Delta;
-      NumValuesUsed = 1;
-    }
+/// DeltaTreeInteriorNode - When isLeaf = false, a node has child pointers.
+/// This class tracks them.
+class DeltaTreeInteriorNode : public DeltaTreeNode {
+  friend class DeltaTreeNode;
 
-    const DeltaTreeNode *getChild(unsigned i) const {
-      assert(i < getNumValuesUsed()+1 && "Invalid child");
-      return Children[i];
-    }
+  DeltaTreeNode *Children[2 * WidthFactor];
 
-    DeltaTreeNode *getChild(unsigned i) {
-      assert(i < getNumValuesUsed()+1 && "Invalid child");
-      return Children[i];
-    }
+  ~DeltaTreeInteriorNode() {
+    for (unsigned i = 0, e = NumValuesUsed + 1; i != e; ++i)
+      Children[i]->Destroy();
+  }
 
-    static bool classof(const DeltaTreeNode *N) { return !N->isLeaf(); }
-  };
+public:
+  DeltaTreeInteriorNode() : DeltaTreeNode(false /*nonleaf*/) {}
+
+  DeltaTreeInteriorNode(const InsertResult &IR)
+      : DeltaTreeNode(false /*nonleaf*/) {
+    Children[0] = IR.LHS;
+    Children[1] = IR.RHS;
+    Values[0] = IR.Split;
+    FullDelta =
+        IR.LHS->getFullDelta() + IR.RHS->getFullDelta() + IR.Split.Delta;
+    NumValuesUsed = 1;
+  }
+
+  const DeltaTreeNode *getChild(unsigned i) const {
+    assert(i < getNumValuesUsed() + 1 && "Invalid child");
+    return Children[i];
+  }
+
+  DeltaTreeNode *getChild(unsigned i) {
+    assert(i < getNumValuesUsed() + 1 && "Invalid child");
+    return Children[i];
+  }
+
+  static bool classof(const DeltaTreeNode *N) { return !N->isLeaf(); }
+};
 
 } // namespace
 
@@ -172,7 +171,7 @@ void DeltaTreeNode::RecomputeFullDeltaLocally() {
   for (unsigned i = 0, e = getNumValuesUsed(); i != e; ++i)
     NewFullDelta += Values[i].Delta;
   if (auto *IN = dyn_cast<DeltaTreeInteriorNode>(this))
-    for (unsigned i = 0, e = getNumValuesUsed()+1; i != e; ++i)
+    for (unsigned i = 0, e = getNumValuesUsed() + 1; i != e; ++i)
       NewFullDelta += IN->getChild(i)->getFullDelta();
   FullDelta = NewFullDelta;
 }
@@ -209,7 +208,7 @@ bool DeltaTreeNode::DoInsertion(unsigned FileIndex, int Delta,
       // For an insertion into a non-full leaf node, just insert the value in
       // its sorted position.  This requires moving later values over.
       if (i != e)
-        memmove(&Values[i+1], &Values[i], sizeof(Values[0])*(e-i));
+        memmove(&Values[i + 1], &Values[i], sizeof(Values[0]) * (e - i));
       Values[i] = SourceDelta::get(FileIndex, Delta);
       ++NumValuesUsed;
       return false;
@@ -239,13 +238,13 @@ bool DeltaTreeNode::DoInsertion(unsigned FileIndex, int Delta,
     // into ourself by moving all the later values/children down, then inserting
     // the new one.
     if (i != e)
-      memmove(&IN->Children[i+2], &IN->Children[i+1],
-              (e-i)*sizeof(IN->Children[0]));
+      memmove(&IN->Children[i + 2], &IN->Children[i + 1],
+              (e - i) * sizeof(IN->Children[0]));
     IN->Children[i] = InsertRes->LHS;
-    IN->Children[i+1] = InsertRes->RHS;
+    IN->Children[i + 1] = InsertRes->RHS;
 
     if (e != i)
-      memmove(&Values[i+1], &Values[i], (e-i)*sizeof(Values[0]));
+      memmove(&Values[i + 1], &Values[i], (e - i) * sizeof(Values[0]));
     Values[i] = InsertRes->Split;
     ++NumValuesUsed;
     return false;
@@ -272,20 +271,21 @@ bool DeltaTreeNode::DoInsertion(unsigned FileIndex, int Delta,
   // SubRHS/SubSplit into.  Find out where to insert SubSplit.
 
   // Find the insertion point, the first delta whose index is >SubSplit.FileLoc.
-  i = 0; e = InsertSide->getNumValuesUsed();
+  i = 0;
+  e = InsertSide->getNumValuesUsed();
   while (i != e && SubSplit.FileLoc > InsertSide->getValue(i).FileLoc)
     ++i;
 
   // Now we know that i is the place to insert the split value into.  Insert it
   // and the child right after it.
   if (i != e)
-    memmove(&InsertSide->Children[i+2], &InsertSide->Children[i+1],
-            (e-i)*sizeof(IN->Children[0]));
-  InsertSide->Children[i+1] = SubRHS;
+    memmove(&InsertSide->Children[i + 2], &InsertSide->Children[i + 1],
+            (e - i) * sizeof(IN->Children[0]));
+  InsertSide->Children[i + 1] = SubRHS;
 
   if (e != i)
-    memmove(&InsertSide->Values[i+1], &InsertSide->Values[i],
-            (e-i)*sizeof(Values[0]));
+    memmove(&InsertSide->Values[i + 1], &InsertSide->Values[i],
+            (e - i) * sizeof(Values[0]));
   InsertSide->Values[i] = SubSplit;
   ++InsertSide->NumValuesUsed;
   InsertSide->FullDelta += SubSplit.Delta + SubRHS->getFullDelta();
@@ -310,7 +310,7 @@ void DeltaTreeNode::DoSplit(InsertResult &InsertRes) {
     // into the new node.
     DeltaTreeInteriorNode *New = new DeltaTreeInteriorNode();
     memcpy(&New->Children[0], &IN->Children[WidthFactor],
-           WidthFactor*sizeof(IN->Children[0]));
+           WidthFactor * sizeof(IN->Children[0]));
     NewNode = New;
   } else {
     // Just create the new leaf node.
@@ -319,10 +319,10 @@ void DeltaTreeNode::DoSplit(InsertResult &InsertRes) {
 
   // Move over the last 'WidthFactor-1' values from here to NewNode.
   memcpy(&NewNode->Values[0], &Values[WidthFactor],
-         (WidthFactor-1)*sizeof(Values[0]));
+         (WidthFactor - 1) * sizeof(Values[0]));
 
   // Decrease the number of values in the two nodes.
-  NewNode->NumValuesUsed = NumValuesUsed = WidthFactor-1;
+  NewNode->NumValuesUsed = NumValuesUsed = WidthFactor - 1;
 
   // Recompute the two nodes' full delta.
   NewNode->RecomputeFullDeltaLocally();
@@ -330,14 +330,14 @@ void DeltaTreeNode::DoSplit(InsertResult &InsertRes) {
 
   InsertRes.LHS = this;
   InsertRes.RHS = NewNode;
-  InsertRes.Split = Values[WidthFactor-1];
+  InsertRes.Split = Values[WidthFactor - 1];
 }
 
 //===----------------------------------------------------------------------===//
 //                        DeltaTree Implementation
 //===----------------------------------------------------------------------===//
 
-//#define VERIFY_TREE
+// #define VERIFY_TREE
 
 #ifdef VERIFY_TREE
 /// VerifyTree - Walk the btree performing assertions on various properties to
@@ -350,7 +350,7 @@ static void VerifyTree(const DeltaTreeNode *N) {
     int FullDelta = 0;
     for (unsigned i = 0, e = N->getNumValuesUsed(); i != e; ++i) {
       if (i)
-        assert(N->getValue(i-1).FileLoc < N->getValue(i).FileLoc);
+        assert(N->getValue(i - 1).FileLoc < N->getValue(i).FileLoc);
       FullDelta += N->getValue(i).Delta;
     }
     assert(FullDelta == N->getFullDelta());
@@ -364,16 +364,16 @@ static void VerifyTree(const DeltaTreeNode *N) {
     const SourceDelta &IVal = N->getValue(i);
     const DeltaTreeNode *IChild = IN->getChild(i);
     if (i)
-      assert(IN->getValue(i-1).FileLoc < IVal.FileLoc);
+      assert(IN->getValue(i - 1).FileLoc < IVal.FileLoc);
     FullDelta += IVal.Delta;
     FullDelta += IChild->getFullDelta();
 
     // The largest value in child #i should be smaller than FileLoc.
-    assert(IChild->getValue(IChild->getNumValuesUsed()-1).FileLoc <
+    assert(IChild->getValue(IChild->getNumValuesUsed() - 1).FileLoc <
            IVal.FileLoc);
 
     // The smallest value in child #i+1 should be larger than FileLoc.
-    assert(IN->getChild(i+1)->getValue(0).FileLoc > IVal.FileLoc);
+    assert(IN->getChild(i + 1)->getValue(0).FileLoc > IVal.FileLoc);
     VerifyTree(IChild);
   }
 
@@ -381,15 +381,11 @@ static void VerifyTree(const DeltaTreeNode *N) {
 
   assert(FullDelta == N->getFullDelta());
 }
-#endif  // VERIFY_TREE
+#endif // VERIFY_TREE
 
-static DeltaTreeNode *getRoot(void *Root) {
-  return (DeltaTreeNode*)Root;
-}
+static DeltaTreeNode *getRoot(void *Root) { return (DeltaTreeNode *)Root; }
 
-DeltaTree::DeltaTree() {
-  Root = new DeltaTreeNode();
-}
+DeltaTree::DeltaTree() { Root = new DeltaTreeNode(); }
 
 DeltaTree::DeltaTree(const DeltaTree &RHS) {
   // Currently we only support copying when the RHS is empty.
@@ -398,9 +394,7 @@ DeltaTree::DeltaTree(const DeltaTree &RHS) {
   Root = new DeltaTreeNode();
 }
 
-DeltaTree::~DeltaTree() {
-  getRoot(Root)->Destroy();
-}
+DeltaTree::~DeltaTree() { getRoot(Root)->Destroy(); }
 
 /// getDeltaAt - Return the accumulated delta at the specified file offset.
 /// This includes all insertions or delections that occurred *before* the
@@ -428,7 +422,8 @@ int DeltaTree::getDeltaAt(unsigned FileIndex) const {
     // If we have an interior node, include information about children and
     // recurse.  Otherwise, if we have a leaf, we're done.
     const auto *IN = dyn_cast<DeltaTreeInteriorNode>(Node);
-    if (!IN) return Result;
+    if (!IN)
+      return Result;
 
     // Include any children to the left of the values we skipped, all of
     // their deltas should be included as well.
@@ -440,7 +435,7 @@ int DeltaTree::getDeltaAt(unsigned FileIndex) const {
     // partial results.
     if (NumValsGreater != Node->getNumValuesUsed() &&
         Node->getValue(NumValsGreater).FileLoc == FileIndex)
-      return Result+IN->getChild(NumValsGreater)->getFullDelta();
+      return Result + IN->getChild(NumValsGreater)->getFullDelta();
 
     // Otherwise, traverse down the tree.  The selected subtree may be
     // partially included in the range.
diff --git a/llvm/lib/Support/RewriteBuffer.cpp b/llvm/lib/Support/RewriteBuffer.cpp
new file mode 100644
index 0000000000000..cc6ba7e97b1a7
--- /dev/null
+++ b/llvm/lib/Support/RewriteBuffer.cpp
@@ -0,0 +1,107 @@
+//===- RewriteBuffer.h - Buffer rewriting interface -----------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/RewriteBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+
+raw_ostream &RewriteBuffer::write(raw_ostream &Stream) const {
+  // Walk RewriteRope chunks efficiently using MoveToNextPiece() instead of the
+  // character iterator.
+  for (RopePieceBTreeIterator I = begin(), E = end(); I != E;
+       I.MoveToNextPiece())
+    Stream << I.piece();
+  return Stream;
+}
+
+/// Return true if this character is non-new-line whitespace:
+/// ' ', '\\t', '\\f', '\\v', '\\r'.
+static inline bool isWhitespaceExceptNL(unsigned char c) {
+  return c == ' ' || c == '\t' || c == '\f' || c == '\v' || c == '\r';
+}
+
+void RewriteBuffer::RemoveText(unsigned OrigOffset, unsigned Size,
+                               bool removeLineIfEmpty) {
+  // Nothing to remove, exit early.
+  if (Size == 0)
+    return;
+
+  unsigned RealOffset = getMappedOffset(OrigOffset, true);
+  assert(RealOffset + Size <= Buffer.size() && "Invalid location");
+
+  // Remove the dead characters.
+  Buffer.erase(RealOffset, Size);
+
+  // Add a delta so that future changes are offset correctly.
+  AddReplaceDelta(OrigOffset, -Size);
+
+  if (removeLineIfEmpty) {
+    // Find the line that the remove occurred and if it is completely empty
+    // remove the line as well.
+
+    iterator curLineStart = begin();
+    unsigned curLineStartOffs = 0;
+    iterator posI = begin();
+    for (unsigned i = 0; i != RealOffset; ++i) {
+      if (*posI == '\n') {
+        curLineStart = posI;
+        ++curLineStart;
+        curLineStartOffs = i + 1;
+      }
+      ++posI;
+    }
+
+    unsigned lineSize = 0;
+    posI = curLineStart;
+    while (posI != end() && isWhitespaceExceptNL(*posI)) {
+      ++posI;
+      ++lineSize;
+    }
+    if (posI != end() && *posI == '\n') {
+      Buffer.erase(curLineStartOffs, lineSize + 1 /* + '\n'*/);
+      // FIXME: Here, the offset of the start of the line is supposed to be
+      // expressed in terms of the original input not the "real" rewrite
+      // buffer.  How do we compute that reliably?  It might be tempting to use
+      // curLineStartOffs + OrigOffset - RealOffset, but that assumes the
+      // difference between the original and real offset is the same at the
+      // removed text and at the start of the line, but that's not true if
+      // edits were previously made earlier on the line.  This bug is also
+      // documented by a FIXME on the definition of
+      // clang::Rewriter::RewriteOptions::RemoveLineIfEmpty.  A reproducer for
+      // the implementation below is the test RemoveLineIfEmpty in
+      // clang/unittests/Rewrite/RewriteBufferTest.cpp.
+      AddReplaceDelta(curLineStartOffs, -(lineSize + 1 /* + '\n'*/));
+    }
+  }
+}
+
+void RewriteBuffer::InsertText(unsigned OrigOffset, StringRef Str,
+                               bool InsertAfter) {
+  // Nothing to insert, exit early.
+  if (Str.empty())
+    return;
+
+  unsigned RealOffset = getMappedOffset(OrigOffset, InsertAfter);
+  Buffer.insert(RealOffset, Str.begin(), Str.end());
+
+  // Add a delta so that future changes are offset correctly.
+  AddInsertDelta(OrigOffset, Str.size());
+}
+
+/// ReplaceText - This method replaces a range of characters in the input
+/// buffer with a new string.  This is effectively a combined "remove+insert"
+/// operation.
+void RewriteBuffer::ReplaceText(unsigned OrigOffset, unsigned OrigLength,
+                                StringRef NewStr) {
+  unsigned RealOffset = getMappedOffset(OrigOffset, true);
+  Buffer.erase(RealOffset, OrigLength);
+  Buffer.insert(RealOffset, NewStr.begin(), NewStr.end());
+  if (OrigLength != NewStr.size())
+    AddReplaceDelta(OrigOffset, NewStr.size() - OrigLength);
+}
diff --git a/clang/lib/Rewrite/RewriteRope.cpp b/llvm/lib/Support/RewriteRope.cpp
similarity index 63%
rename from clang/lib/Rewrite/RewriteRope.cpp
rename to llvm/lib/Support/RewriteRope.cpp
index 980d0f01e277c..7440aa6ab501e 100644
--- a/clang/lib/Rewrite/RewriteRope.cpp
+++ b/llvm/lib/Support/RewriteRope.cpp
@@ -10,14 +10,13 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "clang/Rewrite/Core/RewriteRope.h"
-#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/RewriteRope.h"
 #include "llvm/Support/Casting.h"
 #include <algorithm>
 #include <cassert>
 #include <cstring>
 
-using namespace clang;
+using namespace llvm;
 
 /// RewriteRope is a "strong" string class, designed to make insertions and
 /// deletions in the middle of the string nearly constant time (really, they are
@@ -68,162 +67,160 @@ namespace {
 // RopePieceBTreeNode Class
 //===----------------------------------------------------------------------===//
 
-  /// RopePieceBTreeNode - Common base class of RopePieceBTreeLeaf and
-  /// RopePieceBTreeInterior.  This provides some 'virtual' dispatching methods
-  /// and a flag that determines which subclass the instance is.  Also
-  /// important, this node knows the full extend of the node, including any
-  /// children that it has.  This allows efficient skipping over entire subtrees
-  /// when looking for an offset in the BTree.
-  class RopePieceBTreeNode {
-  protected:
-    /// WidthFactor - This controls the number of K/V slots held in the BTree:
-    /// how wide it is.  Each level of the BTree is guaranteed to have at least
-    /// 'WidthFactor' elements in it (either ropepieces or children), (except
-    /// the root, which may have less) and may have at most 2*WidthFactor
-    /// elements.
-    enum { WidthFactor = 8 };
-
-    /// Size - This is the number of bytes of file this node (including any
-    /// potential children) covers.
-    unsigned Size = 0;
-
-    /// IsLeaf - True if this is an instance of RopePieceBTreeLeaf, false if it
-    /// is an instance of RopePieceBTreeInterior.
-    bool IsLeaf;
-
-    RopePieceBTreeNode(bool isLeaf) : IsLeaf(isLeaf) {}
-    ~RopePieceBTreeNode() = default;
-
-  public:
-    bool isLeaf() const { return IsLeaf; }
-    unsigned size() const { return Size; }
-
-    void Destroy();
-
-    /// split - Split the range containing the specified offset so that we are
-    /// guaranteed that there is a place to do an insertion at the specified
-    /// offset.  The offset is relative, so "0" is the start of the node.
-    ///
-    /// If there is no space in this subtree for the extra piece, the extra tree
-    /// node is returned and must be inserted into a parent.
-    RopePieceBTreeNode *split(unsigned Offset);
-
-    /// insert - Insert the specified ropepiece into this tree node at the
-    /// specified offset.  The offset is relative, so "0" is the start of the
-    /// node.
-    ///
-    /// If there is no space in this subtree for the extra piece, the extra tree
-    /// node is returned and must be inserted into a parent.
-    RopePieceBTreeNode *insert(unsigned Offset, const RopePiece &R);
-
-    /// erase - Remove NumBytes from this node at the specified offset.  We are
-    /// guaranteed that there is a split at Offset.
-    void erase(unsigned Offset, unsigned NumBytes);
-  };
+/// RopePieceBTreeNode - Common base class of RopePieceBTreeLeaf and
+/// RopePieceBTreeInterior.  This provides some 'virtual' dispatching methods
+/// and a flag that determines which subclass the instance is.  Also
+/// important, this node knows the full extend of the node, including any
+/// children that it has.  This allows efficient skipping over entire subtrees
+/// when looking for an offset in the BTree.
+class RopePieceBTreeNode {
+protected:
+  /// WidthFactor - This controls the number of K/V slots held in the BTree:
+  /// how wide it is.  Each level of the BTree is guaranteed to have at least
+  /// 'WidthFactor' elements in it (either ropepieces or children), (except
+  /// the root, which may have less) and may have at most 2*WidthFactor
+  /// elements.
+  enum { WidthFactor = 8 };
+
+  /// Size - This is the number of bytes of file this node (including any
+  /// potential children) covers.
+  unsigned Size = 0;
+
+  /// IsLeaf - True if this is an instance of RopePieceBTreeLeaf, false if it
+  /// is an instance of RopePieceBTreeInterior.
+  bool IsLeaf;
+
+  RopePieceBTreeNode(bool isLeaf) : IsLeaf(isLeaf) {}
+  ~RopePieceBTreeNode() = default;
+
+public:
+  bool isLeaf() const { return IsLeaf; }
+  unsigned size() const { return Size; }
+
+  void Destroy();
+
+  /// split - Split the range containing the specified offset so that we are
+  /// guaranteed that there is a place to do an insertion at the specified
+  /// offset.  The offset is relative, so "0" is the start of the node.
+  ///
+  /// If there is no space in this subtree for the extra piece, the extra tree
+  /// node is returned and must be inserted into a parent.
+  RopePieceBTreeNode *split(unsigned Offset);
+
+  /// insert - Insert the specified ropepiece into this tree node at the
+  /// specified offset.  The offset is relative, so "0" is the start of the
+  /// node.
+  ///
+  /// If there is no space in this subtree for the extra piece, the extra tree
+  /// node is returned and must be inserted into a parent.
+  RopePieceBTreeNode *insert(unsigned Offset, const RopePiece &R);
+
+  /// erase - Remove NumBytes from this node at the specified offset.  We are
+  /// guaranteed that there is a split at Offset.
+  void erase(unsigned Offset, unsigned NumBytes);
+};
 
 //===----------------------------------------------------------------------===//
 // RopePieceBTreeLeaf Class
 //===----------------------------------------------------------------------===//
 
-  /// RopePieceBTreeLeaf - Directly manages up to '2*WidthFactor' RopePiece
-  /// nodes.  This directly represents a chunk of the string with those
-  /// RopePieces concatenated.  Since this is a B+Tree, all values (in this case
-  /// instances of RopePiece) are stored in leaves like this.  To make iteration
-  /// over the leaves efficient, they maintain a singly linked list through the
-  /// NextLeaf field.  This allows the B+Tree forward iterator to be constant
-  /// time for all increments.
-  class RopePieceBTreeLeaf : public RopePieceBTreeNode {
-    /// NumPieces - This holds the number of rope pieces currently active in the
-    /// Pieces array.
-    unsigned char NumPieces = 0;
-
-    /// Pieces - This tracks the file chunks currently in this leaf.
-    RopePiece Pieces[2*WidthFactor];
-
-    /// NextLeaf - This is a pointer to the next leaf in the tree, allowing
-    /// efficient in-order forward iteration of the tree without traversal.
-    RopePieceBTreeLeaf **PrevLeaf = nullptr;
-    RopePieceBTreeLeaf *NextLeaf = nullptr;
-
-  public:
-    RopePieceBTreeLeaf() : RopePieceBTreeNode(true) {}
-
-    ~RopePieceBTreeLeaf() {
-      if (PrevLeaf || NextLeaf)
-        removeFromLeafInOrder();
-      clear();
-    }
+/// RopePieceBTreeLeaf - Directly manages up to '2*WidthFactor' RopePiece
+/// nodes.  This directly represents a chunk of the string with those
+/// RopePieces concatenated.  Since this is a B+Tree, all values (in this case
+/// instances of RopePiece) are stored in leaves like this.  To make iteration
+/// over the leaves efficient, they maintain a singly linked list through the
+/// NextLeaf field.  This allows the B+Tree forward iterator to be constant
+/// time for all increments.
+class RopePieceBTreeLeaf : public RopePieceBTreeNode {
+  /// NumPieces - This holds the number of rope pieces currently active in the
+  /// Pieces array.
+  unsigned char NumPieces = 0;
+
+  /// Pieces - This tracks the file chunks currently in this leaf.
+  RopePiece Pieces[2 * WidthFactor];
+
+  /// NextLeaf - This is a pointer to the next leaf in the tree, allowing
+  /// efficient in-order forward iteration of the tree without traversal.
+  RopePieceBTreeLeaf **PrevLeaf = nullptr;
+  RopePieceBTreeLeaf *NextLeaf = nullptr;
+
+public:
+  RopePieceBTreeLeaf() : RopePieceBTreeNode(true) {}
+
+  ~RopePieceBTreeLeaf() {
+    if (PrevLeaf || NextLeaf)
+      removeFromLeafInOrder();
+    clear();
+  }
 
-    bool isFull() const { return NumPieces == 2*WidthFactor; }
+  bool isFull() const { return NumPieces == 2 * WidthFactor; }
 
-    /// clear - Remove all rope pieces from this leaf.
-    void clear() {
-      while (NumPieces)
-        Pieces[--NumPieces] = RopePiece();
-      Size = 0;
-    }
+  /// clear - Remove all rope pieces from this leaf.
+  void clear() {
+    while (NumPieces)
+      Pieces[--NumPieces] = RopePiece();
+    Size = 0;
+  }
 
-    unsigned getNumPieces() const { return NumPieces; }
+  unsigned getNumPieces() const { return NumPieces; }
 
-    const RopePiece &getPiece(unsigned i) const {
-      assert(i < getNumPieces() && "Invalid piece ID");
-      return Pieces[i];
-    }
+  const RopePiece &getPiece(unsigned i) const {
+    assert(i < getNumPieces() && "Invalid piece ID");
+    return Pieces[i];
+  }
 
-    const RopePieceBTreeLeaf *getNextLeafInOrder() const { return NextLeaf; }
+  const RopePieceBTreeLeaf *getNextLeafInOrder() const { return NextLeaf; }
 
-    void insertAfterLeafInOrder(RopePieceBTreeLeaf *Node) {
-      assert(!PrevLeaf && !NextLeaf && "Already in ordering");
+  void insertAfterLeafInOrder(RopePieceBTreeLeaf *Node) {
+    assert(!PrevLeaf && !NextLeaf && "Already in ordering");
 
-      NextLeaf = Node->NextLeaf;
-      if (NextLeaf)
-        NextLeaf->PrevLeaf = &NextLeaf;
-      PrevLeaf = &Node->NextLeaf;
-      Node->NextLeaf = this;
-    }
+    NextLeaf = Node->NextLeaf;
+    if (NextLeaf)
+      NextLeaf->PrevLeaf = &NextLeaf;
+    PrevLeaf = &Node->NextLeaf;
+    Node->NextLeaf = this;
+  }
 
-    void removeFromLeafInOrder() {
-      if (PrevLeaf) {
-        *PrevLeaf = NextLeaf;
-        if (NextLeaf)
-          NextLeaf->PrevLeaf = PrevLeaf;
-      } else if (NextLeaf) {
-        NextLeaf->PrevLeaf = nullptr;
-      }
+  void removeFromLeafInOrder() {
+    if (PrevLeaf) {
+      *PrevLeaf = NextLeaf;
+      if (NextLeaf)
+        NextLeaf->PrevLeaf = PrevLeaf;
+    } else if (NextLeaf) {
+      NextLeaf->PrevLeaf = nullptr;
     }
+  }
 
-    /// FullRecomputeSizeLocally - This method recomputes the 'Size' field by
-    /// summing the size of all RopePieces.
-    void FullRecomputeSizeLocally() {
-      Size = 0;
-      for (unsigned i = 0, e = getNumPieces(); i != e; ++i)
-        Size += getPiece(i).size();
-    }
+  /// FullRecomputeSizeLocally - This method recomputes the 'Size' field by
+  /// summing the size of all RopePieces.
+  void FullRecomputeSizeLocally() {
+    Size = 0;
+    for (unsigned i = 0, e = getNumPieces(); i != e; ++i)
+      Size += getPiece(i).size();
+  }
 
-    /// split - Split the range containing the specified offset so that we are
-    /// guaranteed that there is a place to do an insertion at the specified
-    /// offset.  The offset is relative, so "0" is the start of the node.
-    ///
-    /// If there is no space in this subtree for the extra piece, the extra tree
-    /// node is returned and must be inserted into a parent.
-    RopePieceBTreeNode *split(unsigned Offset);
-
-    /// insert - Insert the specified ropepiece into this tree node at the
-    /// specified offset.  The offset is relative, so "0" is the start of the
-    /// node.
-    ///
-    /// If there is no space in this subtree for the extra piece, the extra tree
-    /// node is returned and must be inserted into a parent.
-    RopePieceBTreeNode *insert(unsigned Offset, const RopePiece &R);
-
-    /// erase - Remove NumBytes from this node at the specified offset.  We are
-    /// guaranteed that there is a split at Offset.
-    void erase(unsigned Offset, unsigned NumBytes);
-
-    static bool classof(const RopePieceBTreeNode *N) {
-      return N->isLeaf();
-    }
-  };
+  /// split - Split the range containing the specified offset so that we are
+  /// guaranteed that there is a place to do an insertion at the specified
+  /// offset.  The offset is relative, so "0" is the start of the node.
+  ///
+  /// If there is no space in this subtree for the extra piece, the extra tree
+  /// node is returned and must be inserted into a parent.
+  RopePieceBTreeNode *split(unsigned Offset);
+
+  /// insert - Insert the specified ropepiece into this tree node at the
+  /// specified offset.  The offset is relative, so "0" is the start of the
+  /// node.
+  ///
+  /// If there is no space in this subtree for the extra piece, the extra tree
+  /// node is returned and must be inserted into a parent.
+  RopePieceBTreeNode *insert(unsigned Offset, const RopePiece &R);
+
+  /// erase - Remove NumBytes from this node at the specified offset.  We are
+  /// guaranteed that there is a split at Offset.
+  void erase(unsigned Offset, unsigned NumBytes);
+
+  static bool classof(const RopePieceBTreeNode *N) { return N->isLeaf(); }
+};
 
 } // namespace
 
@@ -244,7 +241,7 @@ RopePieceBTreeNode *RopePieceBTreeLeaf::split(unsigned Offset) {
   // Find the piece that this offset lands in.
   unsigned PieceOffs = 0;
   unsigned i = 0;
-  while (Offset >= PieceOffs+Pieces[i].size()) {
+  while (Offset >= PieceOffs + Pieces[i].size()) {
     PieceOffs += Pieces[i].size();
     ++i;
   }
@@ -256,13 +253,13 @@ RopePieceBTreeNode *RopePieceBTreeLeaf::split(unsigned Offset) {
 
   // Otherwise, we need to split piece 'i' at Offset-PieceOffs.  Convert Offset
   // to being Piece relative.
-  unsigned IntraPieceOffset = Offset-PieceOffs;
+  unsigned IntraPieceOffset = Offset - PieceOffs;
 
   // We do this by shrinking the RopePiece and then doing an insert of the tail.
-  RopePiece Tail(Pieces[i].StrData, Pieces[i].StartOffs+IntraPieceOffset,
+  RopePiece Tail(Pieces[i].StrData, Pieces[i].StartOffs + IntraPieceOffset,
                  Pieces[i].EndOffs);
   Size -= Pieces[i].size();
-  Pieces[i].EndOffs = Pieces[i].StartOffs+IntraPieceOffset;
+  Pieces[i].EndOffs = Pieces[i].StartOffs + IntraPieceOffset;
   Size += Pieces[i].size();
 
   return insert(Offset, Tail);
@@ -293,7 +290,7 @@ RopePieceBTreeNode *RopePieceBTreeLeaf::insert(unsigned Offset,
     // For an insertion into a non-full leaf node, just insert the value in
     // its sorted position.  This requires moving later values over.
     for (; i != e; --e)
-      Pieces[e] = Pieces[e-1];
+      Pieces[e] = Pieces[e - 1];
     Pieces[i] = R;
     ++NumPieces;
     Size += R.size();
@@ -309,10 +306,10 @@ RopePieceBTreeNode *RopePieceBTreeLeaf::insert(unsigned Offset,
   RopePieceBTreeLeaf *NewNode = new RopePieceBTreeLeaf();
 
   // Move over the last 'WidthFactor' values from here to NewNode.
-  std::copy(&Pieces[WidthFactor], &Pieces[2*WidthFactor],
+  std::copy(&Pieces[WidthFactor], &Pieces[2 * WidthFactor],
             &NewNode->Pieces[0]);
   // Replace old pieces with null RopePieces to drop refcounts.
-  std::fill(&Pieces[WidthFactor], &Pieces[2*WidthFactor], RopePiece());
+  std::fill(&Pieces[WidthFactor], &Pieces[2 * WidthFactor], RopePiece());
 
   // Decrease the number of values in the two nodes.
   NewNode->NumPieces = NumPieces = WidthFactor;
@@ -347,33 +344,34 @@ void RopePieceBTreeLeaf::erase(unsigned Offset, unsigned NumBytes) {
 
   // Figure out how many pieces completely cover 'NumBytes'.  We want to remove
   // all of them.
-  for (; Offset+NumBytes > PieceOffs+getPiece(i).size(); ++i)
+  for (; Offset + NumBytes > PieceOffs + getPiece(i).size(); ++i)
     PieceOffs += getPiece(i).size();
 
   // If we exactly include the last one, include it in the region to delete.
-  if (Offset+NumBytes == PieceOffs+getPiece(i).size()) {
+  if (Offset + NumBytes == PieceOffs + getPiece(i).size()) {
     PieceOffs += getPiece(i).size();
     ++i;
   }
 
   // If we completely cover some RopePieces, erase them now.
   if (i != StartPiece) {
-    unsigned NumDeleted = i-StartPiece;
+    unsigned NumDeleted = i - StartPiece;
     for (; i != getNumPieces(); ++i)
-      Pieces[i-NumDeleted] = Pieces[i];
+      Pieces[i - NumDeleted] = Pieces[i];
 
     // Drop references to dead rope pieces.
-    std::fill(&Pieces[getNumPieces()-NumDeleted], &Pieces[getNumPieces()],
+    std::fill(&Pieces[getNumPieces() - NumDeleted], &Pieces[getNumPieces()],
               RopePiece());
     NumPieces -= NumDeleted;
 
-    unsigned CoverBytes = PieceOffs-Offset;
+    unsigned CoverBytes = PieceOffs - Offset;
     NumBytes -= CoverBytes;
     Size -= CoverBytes;
   }
 
   // If we completely removed some stuff, we could be done.
-  if (NumBytes == 0) return;
+  if (NumBytes == 0)
+    return;
 
   // Okay, now might be erasing part of some Piece.  If this is the case, then
   // move the start point of the piece.
@@ -390,81 +388,79 @@ void RopePieceBTreeLeaf::erase(unsigned Offset, unsigned NumBytes) {
 
 namespace {
 
-  /// RopePieceBTreeInterior - This represents an interior node in the B+Tree,
-  /// which holds up to 2*WidthFactor pointers to child nodes.
-  class RopePieceBTreeInterior : public RopePieceBTreeNode {
-    /// NumChildren - This holds the number of children currently active in the
-    /// Children array.
-    unsigned char NumChildren = 0;
+/// RopePieceBTreeInterior - This represents an interior node in the B+Tree,
+/// which holds up to 2*WidthFactor pointers to child nodes.
+class RopePieceBTreeInterior : public RopePieceBTreeNode {
+  /// NumChildren - This holds the number of children currently active in the
+  /// Children array.
+  unsigned char NumChildren = 0;
 
-    RopePieceBTreeNode *Children[2*WidthFactor];
+  RopePieceBTreeNode *Children[2 * WidthFactor];
 
-  public:
-    RopePieceBTreeInterior() : RopePieceBTreeNode(false) {}
+public:
+  RopePieceBTreeInterior() : RopePieceBTreeNode(false) {}
 
-    RopePieceBTreeInterior(RopePieceBTreeNode *LHS, RopePieceBTreeNode *RHS)
-        : RopePieceBTreeNode(false) {
-      Children[0] = LHS;
-      Children[1] = RHS;
-      NumChildren = 2;
-      Size = LHS->size() + RHS->size();
-    }
+  RopePieceBTreeInterior(RopePieceBTreeNode *LHS, RopePieceBTreeNode *RHS)
+      : RopePieceBTreeNode(false) {
+    Children[0] = LHS;
+    Children[1] = RHS;
+    NumChildren = 2;
+    Size = LHS->size() + RHS->size();
+  }
 
-    ~RopePieceBTreeInterior() {
-      for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
-        Children[i]->Destroy();
-    }
+  ~RopePieceBTreeInterior() {
+    for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
+      Children[i]->Destroy();
+  }
 
-    bool isFull() const { return NumChildren == 2*WidthFactor; }
+  bool isFull() const { return NumChildren == 2 * WidthFactor; }
 
-    unsigned getNumChildren() const { return NumChildren; }
+  unsigned getNumChildren() const { return NumChildren; }
 
-    const RopePieceBTreeNode *getChild(unsigned i) const {
-      assert(i < NumChildren && "invalid child #");
-      return Children[i];
-    }
+  const RopePieceBTreeNode *getChild(unsigned i) const {
+    assert(i < NumChildren && "invalid child #");
+    return Children[i];
+  }
 
-    RopePieceBTreeNode *getChild(unsigned i) {
-      assert(i < NumChildren && "invalid child #");
-      return Children[i];
-    }
+  RopePieceBTreeNode *getChild(unsigned i) {
+    assert(i < NumChildren && "invalid child #");
+    return Children[i];
+  }
 
-    /// FullRecomputeSizeLocally - Recompute the Size field of this node by
-    /// summing up the sizes of the child nodes.
-    void FullRecomputeSizeLocally() {
-      Size = 0;
-      for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
-        Size += getChild(i)->size();
-    }
+  /// FullRecomputeSizeLocally - Recompute the Size field of this node by
+  /// summing up the sizes of the child nodes.
+  void FullRecomputeSizeLocally() {
+    Size = 0;
+    for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
+      Size += getChild(i)->size();
+  }
 
-    /// split - Split the range containing the specified offset so that we are
-    /// guaranteed that there is a place to do an insertion at the specified
-    /// offset.  The offset is relative, so "0" is the start of the node.
-    ///
-    /// If there is no space in this subtree for the extra piece, the extra tree
-    /// node is returned and must be inserted into a parent.
-    RopePieceBTreeNode *split(unsigned Offset);
-
-    /// insert - Insert the specified ropepiece into this tree node at the
-    /// specified offset.  The offset is relative, so "0" is the start of the
-    /// node.
-    ///
-    /// If there is no space in this subtree for the extra piece, the extra tree
-    /// node is returned and must be inserted into a parent.
-    RopePieceBTreeNode *insert(unsigned Offset, const RopePiece &R);
-
-    /// HandleChildPiece - A child propagated an insertion result up to us.
-    /// Insert the new child, and/or propagate the result further up the tree.
-    RopePieceBTreeNode *HandleChildPiece(unsigned i, RopePieceBTreeNode *RHS);
-
-    /// erase - Remove NumBytes from this node at the specified offset.  We are
-    /// guaranteed that there is a split at Offset.
-    void erase(unsigned Offset, unsigned NumBytes);
-
-    static bool classof(const RopePieceBTreeNode *N) {
-      return !N->isLeaf();
-    }
-  };
+  /// split - Split the range containing the specified offset so that we are
+  /// guaranteed that there is a place to do an insertion at the specified
+  /// offset.  The offset is relative, so "0" is the start of the node.
+  ///
+  /// If there is no space in this subtree for the extra piece, the extra tree
+  /// node is returned and must be inserted into a parent.
+  RopePieceBTreeNode *split(unsigned Offset);
+
+  /// insert - Insert the specified ropepiece into this tree node at the
+  /// specified offset.  The offset is relative, so "0" is the start of the
+  /// node.
+  ///
+  /// If there is no space in this subtree for the extra piece, the extra tree
+  /// node is returned and must be inserted into a parent.
+  RopePieceBTreeNode *insert(unsigned Offset, const RopePiece &R);
+
+  /// HandleChildPiece - A child propagated an insertion result up to us.
+  /// Insert the new child, and/or propagate the result further up the tree.
+  RopePieceBTreeNode *HandleChildPiece(unsigned i, RopePieceBTreeNode *RHS);
+
+  /// erase - Remove NumBytes from this node at the specified offset.  We are
+  /// guaranteed that there is a split at Offset.
+  void erase(unsigned Offset, unsigned NumBytes);
+
+  static bool classof(const RopePieceBTreeNode *N) { return !N->isLeaf(); }
+};
 
 } // namespace
 
@@ -481,7 +477,7 @@ RopePieceBTreeNode *RopePieceBTreeInterior::split(unsigned Offset) {
 
   unsigned ChildOffset = 0;
   unsigned i = 0;
-  for (; Offset >= ChildOffset+getChild(i)->size(); ++i)
+  for (; Offset >= ChildOffset + getChild(i)->size(); ++i)
     ChildOffset += getChild(i)->size();
 
   // If already split there, we're done.
@@ -489,7 +485,7 @@ RopePieceBTreeNode *RopePieceBTreeInterior::split(unsigned Offset) {
     return nullptr;
 
   // Otherwise, recursively split the child.
-  if (RopePieceBTreeNode *RHS = getChild(i)->split(Offset-ChildOffset))
+  if (RopePieceBTreeNode *RHS = getChild(i)->split(Offset - ChildOffset))
     return HandleChildPiece(i, RHS);
   return nullptr; // Done!
 }
@@ -509,17 +505,17 @@ RopePieceBTreeNode *RopePieceBTreeInterior::insert(unsigned Offset,
   unsigned ChildOffs = 0;
   if (Offset == size()) {
     // Fastpath for a common case.  Insert at end of last child.
-    i = e-1;
-    ChildOffs = size()-getChild(i)->size();
+    i = e - 1;
+    ChildOffs = size() - getChild(i)->size();
   } else {
-    for (; Offset > ChildOffs+getChild(i)->size(); ++i)
+    for (; Offset > ChildOffs + getChild(i)->size(); ++i)
       ChildOffs += getChild(i)->size();
   }
 
   Size += R.size();
 
   // Insert at the end of this child.
-  if (RopePieceBTreeNode *RHS = getChild(i)->insert(Offset-ChildOffs, R))
+  if (RopePieceBTreeNode *RHS = getChild(i)->insert(Offset - ChildOffs, R))
     return HandleChildPiece(i, RHS);
 
   return nullptr;
@@ -534,9 +530,9 @@ RopePieceBTreeInterior::HandleChildPiece(unsigned i, RopePieceBTreeNode *RHS) {
   if (!isFull()) {
     // Insert RHS after child 'i'.
     if (i + 1 != getNumChildren())
-      memmove(&Children[i+2], &Children[i+1],
-              (getNumChildren()-i-1)*sizeof(Children[0]));
-    Children[i+1] = RHS;
+      memmove(&Children[i + 2], &Children[i + 1],
+              (getNumChildren() - i - 1) * sizeof(Children[0]));
+    Children[i + 1] = RHS;
     ++NumChildren;
     return nullptr;
   }
@@ -549,7 +545,7 @@ RopePieceBTreeInterior::HandleChildPiece(unsigned i, RopePieceBTreeNode *RHS) {
 
   // Move over the last 'WidthFactor' values from here to NewNode.
   memcpy(&NewNode->Children[0], &Children[WidthFactor],
-         WidthFactor*sizeof(Children[0]));
+         WidthFactor * sizeof(Children[0]));
 
   // Decrease the number of values in the two nodes.
   NewNode->NumChildren = NumChildren = WidthFactor;
@@ -559,7 +555,7 @@ RopePieceBTreeInterior::HandleChildPiece(unsigned i, RopePieceBTreeNode *RHS) {
   if (i < WidthFactor)
     this->HandleChildPiece(i, RHS);
   else
-    NewNode->HandleChildPiece(i-WidthFactor, RHS);
+    NewNode->HandleChildPiece(i - WidthFactor, RHS);
 
   // Recompute the two nodes' size.
   NewNode->FullRecomputeSizeLocally();
@@ -585,7 +581,7 @@ void RopePieceBTreeInterior::erase(unsigned Offset, unsigned NumBytes) {
 
     // If we are deleting something contained entirely in the child, pass on the
     // request.
-    if (Offset+NumBytes < CurChild->size()) {
+    if (Offset + NumBytes < CurChild->size()) {
       CurChild->erase(Offset, NumBytes);
       return;
     }
@@ -593,7 +589,7 @@ void RopePieceBTreeInterior::erase(unsigned Offset, unsigned NumBytes) {
     // If this deletion request starts somewhere in the middle of the child, it
     // must be deleting to the end of the child.
     if (Offset) {
-      unsigned BytesFromChild = CurChild->size()-Offset;
+      unsigned BytesFromChild = CurChild->size() - Offset;
       CurChild->erase(Offset, BytesFromChild);
       NumBytes -= BytesFromChild;
       // Start at the beginning of the next child.
@@ -608,8 +604,8 @@ void RopePieceBTreeInterior::erase(unsigned Offset, unsigned NumBytes) {
     CurChild->Destroy();
     --NumChildren;
     if (i != getNumChildren())
-      memmove(&Children[i], &Children[i+1],
-              (getNumChildren()-i)*sizeof(Children[0]));
+      memmove(&Children[i], &Children[i + 1],
+              (getNumChildren() - i) * sizeof(Children[0]));
   }
 }
 
@@ -654,7 +650,7 @@ RopePieceBTreeNode *RopePieceBTreeNode::insert(unsigned Offset,
 /// erase - Remove NumBytes from this node at the specified offset.  We are
 /// guaranteed that there is a split at Offset.
 void RopePieceBTreeNode::erase(unsigned Offset, unsigned NumBytes) {
-  assert(Offset+NumBytes <= size() && "Invalid offset to erase!");
+  assert(Offset + NumBytes <= size() && "Invalid offset to erase!");
   if (auto *Leaf = dyn_cast<RopePieceBTreeLeaf>(this))
     return Leaf->erase(Offset, NumBytes);
   return cast<RopePieceBTreeInterior>(this)->erase(Offset, NumBytes);
@@ -665,7 +661,7 @@ void RopePieceBTreeNode::erase(unsigned Offset, unsigned NumBytes) {
 //===----------------------------------------------------------------------===//
 
 static const RopePieceBTreeLeaf *getCN(const void *P) {
-  return static_cast<const RopePieceBTreeLeaf*>(P);
+  return static_cast<const RopePieceBTreeLeaf *>(P);
 }
 
 // begin iterator.
@@ -686,13 +682,14 @@ RopePieceBTreeIterator::RopePieceBTreeIterator(const void *n) {
 
   if (CurNode)
     CurPiece = &getCN(CurNode)->getPiece(0);
-  else  // Empty tree, this is an end() iterator.
+  else // Empty tree, this is an end() iterator.
     CurPiece = nullptr;
   CurChar = 0;
 }
 
 void RopePieceBTreeIterator::MoveToNextPiece() {
-  if (CurPiece != &getCN(CurNode)->getPiece(getCN(CurNode)->getNumPieces()-1)) {
+  if (CurPiece !=
+      &getCN(CurNode)->getPiece(getCN(CurNode)->getNumPieces() - 1)) {
     CurChar = 0;
     ++CurPiece;
     return;
@@ -715,25 +712,19 @@ void RopePieceBTreeIterator::MoveToNextPiece() {
 //===----------------------------------------------------------------------===//
 
 static RopePieceBTreeNode *getRoot(void *P) {
-  return static_cast<RopePieceBTreeNode*>(P);
+  return static_cast<RopePieceBTreeNode *>(P);
 }
 
-RopePieceBTree::RopePieceBTree() {
-  Root = new RopePieceBTreeLeaf();
-}
+RopePieceBTree::RopePieceBTree() { Root = new RopePieceBTreeLeaf(); }
 
 RopePieceBTree::RopePieceBTree(const RopePieceBTree &RHS) {
   assert(RHS.empty() && "Can't copy non-empty tree yet");
   Root = new RopePieceBTreeLeaf();
 }
 
-RopePieceBTree::~RopePieceBTree() {
-  getRoot(Root)->Destroy();
-}
+RopePieceBTree::~RopePieceBTree() { getRoot(Root)->Destroy(); }
 
-unsigned RopePieceBTree::size() const {
-  return getRoot(Root)->size();
-}
+unsigned RopePieceBTree::size() const { return getRoot(Root)->size(); }
 
 void RopePieceBTree::clear() {
   if (auto *Leaf = dyn_cast<RopePieceBTreeLeaf>(getRoot(Root)))
@@ -772,24 +763,24 @@ void RopePieceBTree::erase(unsigned Offset, unsigned NumBytes) {
 /// the AllocBuffer object to aggregate requests for small strings into one
 /// allocation instead of doing tons of tiny allocations.
 RopePiece RewriteRope::MakeRopeString(const char *Start, const char *End) {
-  unsigned Len = End-Start;
+  unsigned Len = End - Start;
   assert(Len && "Zero length RopePiece is invalid!");
 
   // If we have space for this string in the current alloc buffer, use it.
-  if (AllocOffs+Len <= AllocChunkSize) {
-    memcpy(AllocBuffer->Data+AllocOffs, Start, Len);
+  if (AllocOffs + Len <= AllocChunkSize) {
+    memcpy(AllocBuffer->Data + AllocOffs, Start, Len);
     AllocOffs += Len;
-    return RopePiece(AllocBuffer, AllocOffs-Len, AllocOffs);
+    return RopePiece(AllocBuffer, AllocOffs - Len, AllocOffs);
   }
 
   // If we don't have enough room because this specific allocation is huge,
   // just allocate a new rope piece for it alone.
   if (Len > AllocChunkSize) {
-    unsigned Size = End-Start+sizeof(RopeRefCountString)-1;
+    unsigned Size = End - Start + sizeof(RopeRefCountString) - 1;
     auto *Res = reinterpret_cast<RopeRefCountString *>(new char[Size]);
     Res->RefCount = 0;
-    memcpy(Res->Data, Start, End-Start);
-    return RopePiece(Res, 0, End-Start);
+    memcpy(Res->Data, Start, End - Start);
+    return RopePiece(Res, 0, End - Start);
   }
 
   // Otherwise, this was a small request but we just don't have space for it
diff --git a/llvm/unittests/ADT/CMakeLists.txt b/llvm/unittests/ADT/CMakeLists.txt
index f48d840a10595..745e4d9fb74a4 100644
--- a/llvm/unittests/ADT/CMakeLists.txt
+++ b/llvm/unittests/ADT/CMakeLists.txt
@@ -63,6 +63,7 @@ add_llvm_unittest(ADTTests
   PostOrderIteratorTest.cpp
   PriorityWorklistTest.cpp
   RangeAdapterTest.cpp
+  RewriteBufferTest.cpp
   SCCIteratorTest.cpp
   STLExtrasTest.cpp
   STLForwardCompatTest.cpp
diff --git a/clang/unittests/Rewrite/RewriteBufferTest.cpp b/llvm/unittests/ADT/RewriteBufferTest.cpp
similarity index 96%
rename from clang/unittests/Rewrite/RewriteBufferTest.cpp
rename to llvm/unittests/ADT/RewriteBufferTest.cpp
index bf29c0ff92830..3b367daa7806e 100644
--- a/clang/unittests/Rewrite/RewriteBufferTest.cpp
+++ b/llvm/unittests/ADT/RewriteBufferTest.cpp
@@ -6,11 +6,10 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "clang/Rewrite/Core/RewriteBuffer.h"
+#include "llvm/ADT/RewriteBuffer.h"
 #include "gtest/gtest.h"
 
 using namespace llvm;
-using namespace clang;
 
 namespace {
 
@@ -32,7 +31,7 @@ static void tagRange(unsigned Offset, unsigned Len, StringRef tagName,
   raw_string_ostream(EndTag) << "</" << tagName << '>';
 
   Buf.InsertTextAfter(Offset, BeginTag);
-  Buf.InsertTextBefore(Offset+Len, EndTag);
+  Buf.InsertTextBefore(Offset + Len, EndTag);
 }
 
 TEST(RewriteBuffer, TagRanges) {



More information about the cfe-commits mailing list