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