18b0c2f659d350118cceee33c211a3dd5e3138ac2Chris Lattner//===--- RewriteRope.h - Rope specialized for rewriter ----------*- C++ -*-===//
28b0c2f659d350118cceee33c211a3dd5e3138ac2Chris Lattner//
38b0c2f659d350118cceee33c211a3dd5e3138ac2Chris Lattner//                     The LLVM Compiler Infrastructure
48b0c2f659d350118cceee33c211a3dd5e3138ac2Chris Lattner//
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details.
78b0c2f659d350118cceee33c211a3dd5e3138ac2Chris Lattner//
88b0c2f659d350118cceee33c211a3dd5e3138ac2Chris Lattner//===----------------------------------------------------------------------===//
98b0c2f659d350118cceee33c211a3dd5e3138ac2Chris Lattner//
108b0c2f659d350118cceee33c211a3dd5e3138ac2Chris Lattner//  This file defines the RewriteRope class, which is a powerful string class.
118b0c2f659d350118cceee33c211a3dd5e3138ac2Chris Lattner//
128b0c2f659d350118cceee33c211a3dd5e3138ac2Chris Lattner//===----------------------------------------------------------------------===//
138b0c2f659d350118cceee33c211a3dd5e3138ac2Chris Lattner
148b0c2f659d350118cceee33c211a3dd5e3138ac2Chris Lattner#ifndef LLVM_CLANG_REWRITEROPE_H
158b0c2f659d350118cceee33c211a3dd5e3138ac2Chris Lattner#define LLVM_CLANG_REWRITEROPE_H
168b0c2f659d350118cceee33c211a3dd5e3138ac2Chris Lattner
17f56faa01936b9cf909623d7f06e3c2569ca4a78eDmitri Gribenko#include "llvm/Support/Compiler.h"
182c33a164371482b43a13e500dbb4d3278605c5f4Steve Naroff#include <cassert>
19ea3fe7c72b73ae09070ced4dc12ddbfbd29c0b1aDaniel Dunbar#include <cstddef>
2030a2e16f6c27f888dd11eba6bbbae1e980078fcbChandler Carruth#include <cstring>
21f5afb5e1fa1877a4adf3328e5be31b2f959d82ebGabor Greif#include <iterator>
228b0c2f659d350118cceee33c211a3dd5e3138ac2Chris Lattner
238b0c2f659d350118cceee33c211a3dd5e3138ac2Chris Lattnernamespace clang {
245fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner  //===--------------------------------------------------------------------===//
255fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner  // RopeRefCountString Class
265fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner  //===--------------------------------------------------------------------===//
271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
285618d88b93056bae76845b1503cce6ba0a6080f1Chris Lattner  /// RopeRefCountString - This struct is allocated with 'new char[]' from the
295618d88b93056bae76845b1503cce6ba0a6080f1Chris Lattner  /// heap, and represents a reference counted chunk of string data.  When its
305618d88b93056bae76845b1503cce6ba0a6080f1Chris Lattner  /// ref count drops to zero, it is delete[]'d.  This is primarily managed
315618d88b93056bae76845b1503cce6ba0a6080f1Chris Lattner  /// through the RopePiece class below.
325fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner  struct RopeRefCountString {
335fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    unsigned RefCount;
345fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    char Data[1];  //  Variable sized.
351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
365fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    void addRef() {
37a8eaf008e92759142982f7b40720b2b2674bd663Richard Smith      ++RefCount;
385fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    }
391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
405fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    void dropRef() {
41a8eaf008e92759142982f7b40720b2b2674bd663Richard Smith      if (--RefCount == 0)
425fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner        delete [] (char*)this;
435fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    }
445fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner  };
451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
465fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner  //===--------------------------------------------------------------------===//
475fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner  // RopePiece Class
485fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner  //===--------------------------------------------------------------------===//
491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
505618d88b93056bae76845b1503cce6ba0a6080f1Chris Lattner  /// RopePiece - This class represents a view into a RopeRefCountString object.
515618d88b93056bae76845b1503cce6ba0a6080f1Chris Lattner  /// This allows references to string data to be efficiently chopped up and
525618d88b93056bae76845b1503cce6ba0a6080f1Chris Lattner  /// moved around without having to push around the string data itself.
535618d88b93056bae76845b1503cce6ba0a6080f1Chris Lattner  ///
545618d88b93056bae76845b1503cce6ba0a6080f1Chris Lattner  /// For example, we could have a 1M RopePiece and want to insert something
555618d88b93056bae76845b1503cce6ba0a6080f1Chris Lattner  /// into the middle of it.  To do this, we split it into two RopePiece objects
565618d88b93056bae76845b1503cce6ba0a6080f1Chris Lattner  /// that both refer to the same underlying RopeRefCountString (just with
575618d88b93056bae76845b1503cce6ba0a6080f1Chris Lattner  /// different offsets) which is a nice constant time operation.
585fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner  struct RopePiece {
595fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    RopeRefCountString *StrData;
605fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    unsigned StartOffs;
615fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    unsigned EndOffs;
621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
635fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    RopePiece() : StrData(0), StartOffs(0), EndOffs(0) {}
641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
655fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    RopePiece(RopeRefCountString *Str, unsigned Start, unsigned End)
665618d88b93056bae76845b1503cce6ba0a6080f1Chris Lattner      : StrData(Str), StartOffs(Start), EndOffs(End) {
67a8eaf008e92759142982f7b40720b2b2674bd663Richard Smith      if (StrData)
68a8eaf008e92759142982f7b40720b2b2674bd663Richard Smith        StrData->addRef();
69febe719596ee68605944da5f2e03258e18e6df8cChris Lattner    }
705fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    RopePiece(const RopePiece &RP)
715618d88b93056bae76845b1503cce6ba0a6080f1Chris Lattner      : StrData(RP.StrData), StartOffs(RP.StartOffs), EndOffs(RP.EndOffs) {
72a8eaf008e92759142982f7b40720b2b2674bd663Richard Smith      if (StrData)
73a8eaf008e92759142982f7b40720b2b2674bd663Richard Smith        StrData->addRef();
74febe719596ee68605944da5f2e03258e18e6df8cChris Lattner    }
751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
765fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    ~RopePiece() {
77a8eaf008e92759142982f7b40720b2b2674bd663Richard Smith      if (StrData)
78a8eaf008e92759142982f7b40720b2b2674bd663Richard Smith        StrData->dropRef();
795fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    }
801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
815fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    void operator=(const RopePiece &RHS) {
825fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner      if (StrData != RHS.StrData) {
83a8eaf008e92759142982f7b40720b2b2674bd663Richard Smith        if (StrData)
84a8eaf008e92759142982f7b40720b2b2674bd663Richard Smith          StrData->dropRef();
855fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner        StrData = RHS.StrData;
86a8eaf008e92759142982f7b40720b2b2674bd663Richard Smith        if (StrData)
87a8eaf008e92759142982f7b40720b2b2674bd663Richard Smith          StrData->addRef();
885fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner      }
895fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner      StartOffs = RHS.StartOffs;
905fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner      EndOffs = RHS.EndOffs;
91febe719596ee68605944da5f2e03258e18e6df8cChris Lattner    }
921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
935fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    const char &operator[](unsigned Offset) const {
945fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner      return StrData->Data[Offset+StartOffs];
955fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    }
965fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    char &operator[](unsigned Offset) {
975fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner      return StrData->Data[Offset+StartOffs];
98febe719596ee68605944da5f2e03258e18e6df8cChris Lattner    }
991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1005fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    unsigned size() const { return EndOffs-StartOffs; }
1015fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner  };
1021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1035fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner  //===--------------------------------------------------------------------===//
1045fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner  // RopePieceBTreeIterator Class
1055fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner  //===--------------------------------------------------------------------===//
1061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1075618d88b93056bae76845b1503cce6ba0a6080f1Chris Lattner  /// RopePieceBTreeIterator - This class provides read-only forward iteration
1085618d88b93056bae76845b1503cce6ba0a6080f1Chris Lattner  /// over bytes that are in a RopePieceBTree.  This first iterates over bytes
1095618d88b93056bae76845b1503cce6ba0a6080f1Chris Lattner  /// in a RopePiece, then iterates over RopePiece's in a RopePieceBTreeLeaf,
1105618d88b93056bae76845b1503cce6ba0a6080f1Chris Lattner  /// then iterates over RopePieceBTreeLeaf's in a RopePieceBTree.
1115fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner  class RopePieceBTreeIterator :
112cf78271b0a932b94598a9dec83fb33046fd033ceGabor Greif      public std::iterator<std::forward_iterator_tag, const char, ptrdiff_t> {
1135fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    /// CurNode - The current B+Tree node that we are inspecting.
1145fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    const void /*RopePieceBTreeLeaf*/ *CurNode;
1155fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    /// CurPiece - The current RopePiece in the B+Tree node that we're
1165fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    /// inspecting.
1175fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    const RopePiece *CurPiece;
1185fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    /// CurChar - The current byte in the RopePiece we are pointing to.
1195fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    unsigned CurChar;
1205fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner  public:
1215fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    // begin iterator.
1225fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    RopePieceBTreeIterator(const void /*RopePieceBTreeNode*/ *N);
1235fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    // end iterator
1245fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    RopePieceBTreeIterator() : CurNode(0), CurPiece(0), CurChar(0) {}
1251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
126fe5042e287352d00db89508bf3c1373cc44b85dbSeo Sanghyeon    char operator*() const {
1275fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner      return (*CurPiece)[CurChar];
1285fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    }
1291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1305fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    bool operator==(const RopePieceBTreeIterator &RHS) const {
1315fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner      return CurPiece == RHS.CurPiece && CurChar == RHS.CurChar;
132febe719596ee68605944da5f2e03258e18e6df8cChris Lattner    }
1335fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    bool operator!=(const RopePieceBTreeIterator &RHS) const {
1345fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner      return !operator==(RHS);
135febe719596ee68605944da5f2e03258e18e6df8cChris Lattner    }
1361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1375fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    RopePieceBTreeIterator& operator++() {   // Preincrement
1385fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner      if (CurChar+1 < CurPiece->size())
1395fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner        ++CurChar;
1405fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner      else
1415fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner        MoveToNextPiece();
1425fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner      return *this;
1435fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    }
1445fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    inline RopePieceBTreeIterator operator++(int) { // Postincrement
1455fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner      RopePieceBTreeIterator tmp = *this; ++*this; return tmp;
1465fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    }
1475fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner  private:
1485fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    void MoveToNextPiece();
1495fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner  };
1501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1515fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner  //===--------------------------------------------------------------------===//
1525fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner  // RopePieceBTree Class
1535fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner  //===--------------------------------------------------------------------===//
1541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1555fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner  class RopePieceBTree {
1565fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    void /*RopePieceBTreeNode*/ *Root;
157f56faa01936b9cf909623d7f06e3c2569ca4a78eDmitri Gribenko    void operator=(const RopePieceBTree &) LLVM_DELETED_FUNCTION;
1585fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner  public:
1595fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    RopePieceBTree();
1605fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    RopePieceBTree(const RopePieceBTree &RHS);
1615fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    ~RopePieceBTree();
1621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1635fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    typedef RopePieceBTreeIterator iterator;
1645fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    iterator begin() const { return iterator(Root); }
1655fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    iterator end() const { return iterator(); }
1665fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    unsigned size() const;
1675fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    unsigned empty() const { return size() == 0; }
1681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1695fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    void clear();
1701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1715fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    void insert(unsigned Offset, const RopePiece &R);
1725fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner
1735fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner    void erase(unsigned Offset, unsigned NumBytes);
1745fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner  };
175febe719596ee68605944da5f2e03258e18e6df8cChris Lattner
1765fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner  //===--------------------------------------------------------------------===//
1775fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner  // RewriteRope Class
1785fd3e2673a1bd61d5f08f679555d15d23aba9314Chris Lattner  //===--------------------------------------------------------------------===//
1791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1805618d88b93056bae76845b1503cce6ba0a6080f1Chris Lattner/// RewriteRope - A powerful string class.  This class supports extremely
1815618d88b93056bae76845b1503cce6ba0a6080f1Chris Lattner/// efficient insertions and deletions into the middle of it, even for
1825618d88b93056bae76845b1503cce6ba0a6080f1Chris Lattner/// ridiculously long strings.
1838b0c2f659d350118cceee33c211a3dd5e3138ac2Chris Lattnerclass RewriteRope {
184febe719596ee68605944da5f2e03258e18e6df8cChris Lattner  RopePieceBTree Chunks;
1851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1866969fd4292adfa44024f3bdac7c45bcfee75754fChris Lattner  /// We allocate space for string data out of a buffer of size AllocChunkSize.
1876969fd4292adfa44024f3bdac7c45bcfee75754fChris Lattner  /// This keeps track of how much space is left.
1886969fd4292adfa44024f3bdac7c45bcfee75754fChris Lattner  RopeRefCountString *AllocBuffer;
1896969fd4292adfa44024f3bdac7c45bcfee75754fChris Lattner  unsigned AllocOffs;
1906969fd4292adfa44024f3bdac7c45bcfee75754fChris Lattner  enum { AllocChunkSize = 4080 };
1913d2e8c7b70d5719d00b919708fdd5a45cffda836Chris Lattner
1928b0c2f659d350118cceee33c211a3dd5e3138ac2Chris Lattnerpublic:
193e5cd857f7e71d5789df25d5046d104b93cf2a71cChris Lattner  RewriteRope() :  AllocBuffer(0), AllocOffs(AllocChunkSize) {}
1941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  RewriteRope(const RewriteRope &RHS)
195e5cd857f7e71d5789df25d5046d104b93cf2a71cChris Lattner    : Chunks(RHS.Chunks), AllocBuffer(0), AllocOffs(AllocChunkSize) {
196febe719596ee68605944da5f2e03258e18e6df8cChris Lattner  }
197febe719596ee68605944da5f2e03258e18e6df8cChris Lattner
198febe719596ee68605944da5f2e03258e18e6df8cChris Lattner  ~RewriteRope() {
199febe719596ee68605944da5f2e03258e18e6df8cChris Lattner    // If we had an allocation buffer, drop our reference to it.
200a8eaf008e92759142982f7b40720b2b2674bd663Richard Smith    if (AllocBuffer)
201a8eaf008e92759142982f7b40720b2b2674bd663Richard Smith      AllocBuffer->dropRef();
202febe719596ee68605944da5f2e03258e18e6df8cChris Lattner  }
2031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
204febe719596ee68605944da5f2e03258e18e6df8cChris Lattner  typedef RopePieceBTree::iterator iterator;
205febe719596ee68605944da5f2e03258e18e6df8cChris Lattner  typedef RopePieceBTree::iterator const_iterator;
206febe719596ee68605944da5f2e03258e18e6df8cChris Lattner  iterator begin() const { return Chunks.begin(); }
207febe719596ee68605944da5f2e03258e18e6df8cChris Lattner  iterator end() const  { return Chunks.end(); }
208febe719596ee68605944da5f2e03258e18e6df8cChris Lattner  unsigned size() const { return Chunks.size(); }
2091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2108b0c2f659d350118cceee33c211a3dd5e3138ac2Chris Lattner  void clear() {
2118b0c2f659d350118cceee33c211a3dd5e3138ac2Chris Lattner    Chunks.clear();
2128b0c2f659d350118cceee33c211a3dd5e3138ac2Chris Lattner  }
2131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
214febe719596ee68605944da5f2e03258e18e6df8cChris Lattner  void assign(const char *Start, const char *End) {
215febe719596ee68605944da5f2e03258e18e6df8cChris Lattner    clear();
216c66d0aa934f2afd412f50881a5e959bb8582cf14Chris Lattner    if (Start != End)
217c66d0aa934f2afd412f50881a5e959bb8582cf14Chris Lattner      Chunks.insert(0, MakeRopeString(Start, End));
218febe719596ee68605944da5f2e03258e18e6df8cChris Lattner  }
2191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
220febe719596ee68605944da5f2e03258e18e6df8cChris Lattner  void insert(unsigned Offset, const char *Start, const char *End) {
2210d3ab3f121ff6c2a38acde4e93a28980b824d045Chris Lattner    assert(Offset <= size() && "Invalid position to insert!");
222febe719596ee68605944da5f2e03258e18e6df8cChris Lattner    if (Start == End) return;
223febe719596ee68605944da5f2e03258e18e6df8cChris Lattner    Chunks.insert(Offset, MakeRopeString(Start, End));
224febe719596ee68605944da5f2e03258e18e6df8cChris Lattner  }
225febe719596ee68605944da5f2e03258e18e6df8cChris Lattner
226febe719596ee68605944da5f2e03258e18e6df8cChris Lattner  void erase(unsigned Offset, unsigned NumBytes) {
2270d3ab3f121ff6c2a38acde4e93a28980b824d045Chris Lattner    assert(Offset+NumBytes <= size() && "Invalid region to erase!");
228febe719596ee68605944da5f2e03258e18e6df8cChris Lattner    if (NumBytes == 0) return;
229febe719596ee68605944da5f2e03258e18e6df8cChris Lattner    Chunks.erase(Offset, NumBytes);
230febe719596ee68605944da5f2e03258e18e6df8cChris Lattner  }
2318b0c2f659d350118cceee33c211a3dd5e3138ac2Chris Lattner
2328b0c2f659d350118cceee33c211a3dd5e3138ac2Chris Lattnerprivate:
2335618d88b93056bae76845b1503cce6ba0a6080f1Chris Lattner  RopePiece MakeRopeString(const char *Start, const char *End);
2348b0c2f659d350118cceee33c211a3dd5e3138ac2Chris Lattner};
2351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2368b0c2f659d350118cceee33c211a3dd5e3138ac2Chris Lattner} // end namespace clang
2378b0c2f659d350118cceee33c211a3dd5e3138ac2Chris Lattner
2388b0c2f659d350118cceee33c211a3dd5e3138ac2Chris Lattner#endif
239