17 using namespace clang;
74 class RopePieceBTreeNode {
81 enum { WidthFactor = 8 };
91 RopePieceBTreeNode(
bool isLeaf) : Size(0), IsLeaf(isLeaf) {}
92 ~RopePieceBTreeNode() =
default;
95 bool isLeaf()
const {
return IsLeaf; }
96 unsigned size()
const {
return Size; }
106 RopePieceBTreeNode *split(
unsigned Offset);
118 void erase(
unsigned Offset,
unsigned NumBytes);
135 class RopePieceBTreeLeaf :
public RopePieceBTreeNode {
138 unsigned char NumPieces;
146 RopePieceBTreeLeaf **PrevLeaf, *NextLeaf;
148 RopePieceBTreeLeaf() : RopePieceBTreeNode(
true), NumPieces(0),
149 PrevLeaf(nullptr), NextLeaf(nullptr) {}
150 ~RopePieceBTreeLeaf() {
151 if (PrevLeaf || NextLeaf)
152 removeFromLeafInOrder();
156 bool isFull()
const {
return NumPieces == 2*WidthFactor; }
165 unsigned getNumPieces()
const {
return NumPieces; }
167 const RopePiece &getPiece(
unsigned i)
const {
168 assert(i < getNumPieces() &&
"Invalid piece ID");
172 const RopePieceBTreeLeaf *getNextLeafInOrder()
const {
return NextLeaf; }
173 void insertAfterLeafInOrder(RopePieceBTreeLeaf *
Node) {
174 assert(!PrevLeaf && !NextLeaf &&
"Already in ordering");
176 NextLeaf = Node->NextLeaf;
178 NextLeaf->PrevLeaf = &NextLeaf;
179 PrevLeaf = &Node->NextLeaf;
180 Node->NextLeaf =
this;
183 void removeFromLeafInOrder() {
185 *PrevLeaf = NextLeaf;
187 NextLeaf->PrevLeaf = PrevLeaf;
188 }
else if (NextLeaf) {
189 NextLeaf->PrevLeaf =
nullptr;
195 void FullRecomputeSizeLocally() {
197 for (
unsigned i = 0, e = getNumPieces(); i != e; ++i)
198 Size += getPiece(i).size();
207 RopePieceBTreeNode *split(
unsigned Offset);
220 void erase(
unsigned Offset,
unsigned NumBytes);
222 static inline bool classof(
const RopePieceBTreeNode *N) {
234 RopePieceBTreeNode *RopePieceBTreeLeaf::split(
unsigned Offset) {
237 if (Offset == 0 || Offset == size()) {
243 unsigned PieceOffs = 0;
245 while (Offset >= PieceOffs+Pieces[i].size()) {
246 PieceOffs += Pieces[i].size();
252 if (PieceOffs == Offset)
257 unsigned IntraPieceOffset = Offset-PieceOffs;
260 RopePiece Tail(Pieces[i].StrData, Pieces[i].StartOffs+IntraPieceOffset,
262 Size -= Pieces[i].size();
263 Pieces[i].EndOffs = Pieces[i].StartOffs+IntraPieceOffset;
264 Size += Pieces[i].size();
266 return insert(Offset, Tail);
275 RopePieceBTreeNode *RopePieceBTreeLeaf::insert(
unsigned Offset,
281 unsigned i = 0, e = getNumPieces();
282 if (Offset == size()) {
286 unsigned SlotOffs = 0;
287 for (; Offset > SlotOffs; ++i)
288 SlotOffs += getPiece(i).size();
289 assert(SlotOffs == Offset &&
"Split didn't occur before insertion!");
295 Pieces[e] = Pieces[e-1];
308 RopePieceBTreeLeaf *NewNode =
new RopePieceBTreeLeaf();
311 std::copy(&Pieces[WidthFactor], &Pieces[2*WidthFactor],
312 &NewNode->Pieces[0]);
314 std::fill(&Pieces[WidthFactor], &Pieces[2*WidthFactor],
RopePiece());
317 NewNode->NumPieces = NumPieces = WidthFactor;
320 NewNode->FullRecomputeSizeLocally();
321 FullRecomputeSizeLocally();
324 NewNode->insertAfterLeafInOrder(
this);
327 if (this->size() >= Offset)
328 this->insert(Offset, R);
330 NewNode->insert(Offset - this->size(), R);
336 void RopePieceBTreeLeaf::erase(
unsigned Offset,
unsigned NumBytes) {
339 unsigned PieceOffs = 0;
341 for (; Offset > PieceOffs; ++i)
342 PieceOffs += getPiece(i).size();
343 assert(PieceOffs == Offset &&
"Split didn't occur before erase!");
345 unsigned StartPiece = i;
349 for (; Offset+NumBytes > PieceOffs+getPiece(i).size(); ++i)
350 PieceOffs += getPiece(i).size();
353 if (Offset+NumBytes == PieceOffs+getPiece(i).size())
354 PieceOffs += getPiece(i).size(), ++i;
357 if (i != StartPiece) {
358 unsigned NumDeleted = i-StartPiece;
359 for (; i != getNumPieces(); ++i)
360 Pieces[i-NumDeleted] = Pieces[i];
363 std::fill(&Pieces[getNumPieces()-NumDeleted], &Pieces[getNumPieces()],
365 NumPieces -= NumDeleted;
367 unsigned CoverBytes = PieceOffs-
Offset;
368 NumBytes -= CoverBytes;
373 if (NumBytes == 0)
return;
377 assert(getPiece(StartPiece).size() > NumBytes);
378 Pieces[StartPiece].StartOffs += NumBytes;
391 class RopePieceBTreeInterior :
public RopePieceBTreeNode {
394 unsigned char NumChildren;
395 RopePieceBTreeNode *Children[2*WidthFactor];
397 RopePieceBTreeInterior() : RopePieceBTreeNode(
false), NumChildren(0) {}
399 RopePieceBTreeInterior(RopePieceBTreeNode *LHS, RopePieceBTreeNode *RHS)
400 : RopePieceBTreeNode(
false) {
404 Size = LHS->size() + RHS->size();
407 ~RopePieceBTreeInterior() {
408 for (
unsigned i = 0, e = getNumChildren(); i != e; ++i)
409 Children[i]->Destroy();
412 bool isFull()
const {
return NumChildren == 2*WidthFactor; }
414 unsigned getNumChildren()
const {
return NumChildren; }
415 const RopePieceBTreeNode *getChild(
unsigned i)
const {
416 assert(i < NumChildren &&
"invalid child #");
419 RopePieceBTreeNode *getChild(
unsigned i) {
420 assert(i < NumChildren &&
"invalid child #");
426 void FullRecomputeSizeLocally() {
428 for (
unsigned i = 0, e = getNumChildren(); i != e; ++i)
429 Size += getChild(i)->size();
439 RopePieceBTreeNode *split(
unsigned Offset);
448 RopePieceBTreeNode *insert(
unsigned Offset,
const RopePiece &R);
452 RopePieceBTreeNode *HandleChildPiece(
unsigned i, RopePieceBTreeNode *RHS);
456 void erase(
unsigned Offset,
unsigned NumBytes);
458 static inline bool classof(
const RopePieceBTreeNode *N) {
470 RopePieceBTreeNode *RopePieceBTreeInterior::split(
unsigned Offset) {
472 if (Offset == 0 || Offset == size())
475 unsigned ChildOffset = 0;
477 for (; Offset >= ChildOffset+getChild(i)->size(); ++i)
478 ChildOffset += getChild(i)->size();
481 if (ChildOffset == Offset)
485 if (RopePieceBTreeNode *RHS = getChild(i)->split(Offset-ChildOffset))
486 return HandleChildPiece(i, RHS);
496 RopePieceBTreeNode *RopePieceBTreeInterior::insert(
unsigned Offset,
500 unsigned i = 0, e = getNumChildren();
502 unsigned ChildOffs = 0;
503 if (Offset == size()) {
506 ChildOffs = size()-getChild(i)->size();
508 for (; Offset > ChildOffs+getChild(i)->size(); ++i)
509 ChildOffs += getChild(i)->size();
515 if (RopePieceBTreeNode *RHS = getChild(i)->insert(Offset-ChildOffs, R))
516 return HandleChildPiece(i, RHS);
524 RopePieceBTreeInterior::HandleChildPiece(
unsigned i, RopePieceBTreeNode *RHS) {
529 if (i + 1 != getNumChildren())
530 memmove(&Children[i+2], &Children[i+1],
531 (getNumChildren()-i-1)*
sizeof(Children[0]));
541 RopePieceBTreeInterior *NewNode =
new RopePieceBTreeInterior();
544 memcpy(&NewNode->Children[0], &Children[WidthFactor],
545 WidthFactor*
sizeof(Children[0]));
548 NewNode->NumChildren = NumChildren = WidthFactor;
553 this->HandleChildPiece(i, RHS);
555 NewNode->HandleChildPiece(i-WidthFactor, RHS);
558 NewNode->FullRecomputeSizeLocally();
559 FullRecomputeSizeLocally();
565 void RopePieceBTreeInterior::erase(
unsigned Offset,
unsigned NumBytes) {
571 for (; Offset >= getChild(i)->size(); ++i)
572 Offset -= getChild(i)->size();
577 RopePieceBTreeNode *CurChild = getChild(i);
581 if (Offset+NumBytes < CurChild->size()) {
582 CurChild->erase(Offset, NumBytes);
589 unsigned BytesFromChild = CurChild->size()-
Offset;
590 CurChild->erase(Offset, BytesFromChild);
591 NumBytes -= BytesFromChild;
600 NumBytes -= CurChild->size();
603 if (i != getNumChildren())
604 memmove(&Children[i], &Children[i+1],
605 (getNumChildren()-i)*
sizeof(Children[0]));
613 void RopePieceBTreeNode::Destroy() {
614 if (RopePieceBTreeLeaf *Leaf = dyn_cast<RopePieceBTreeLeaf>(
this))
617 delete cast<RopePieceBTreeInterior>(
this);
626 RopePieceBTreeNode *RopePieceBTreeNode::split(
unsigned Offset) {
627 assert(Offset <= size() &&
"Invalid offset to split!");
628 if (RopePieceBTreeLeaf *Leaf = dyn_cast<RopePieceBTreeLeaf>(
this))
629 return Leaf->split(Offset);
630 return cast<RopePieceBTreeInterior>(
this)->split(Offset);
639 RopePieceBTreeNode *RopePieceBTreeNode::insert(
unsigned Offset,
641 assert(Offset <= size() &&
"Invalid offset to insert!");
642 if (RopePieceBTreeLeaf *Leaf = dyn_cast<RopePieceBTreeLeaf>(
this))
643 return Leaf->insert(Offset, R);
644 return cast<RopePieceBTreeInterior>(
this)->insert(Offset, R);
649 void RopePieceBTreeNode::erase(
unsigned Offset,
unsigned NumBytes) {
650 assert(Offset+NumBytes <= size() &&
"Invalid offset to erase!");
651 if (RopePieceBTreeLeaf *Leaf = dyn_cast<RopePieceBTreeLeaf>(
this))
652 return Leaf->erase(Offset, NumBytes);
653 return cast<RopePieceBTreeInterior>(
this)->erase(Offset, NumBytes);
661 static const RopePieceBTreeLeaf *
getCN(
const void *
P) {
662 return static_cast<const RopePieceBTreeLeaf*
>(
P);
667 const RopePieceBTreeNode *N =
static_cast<const RopePieceBTreeNode*
>(n);
670 while (
const RopePieceBTreeInterior *IN = dyn_cast<RopePieceBTreeInterior>(N))
674 CurNode = cast<RopePieceBTreeLeaf>(N);
678 while (CurNode &&
getCN(CurNode)->getNumPieces() == 0)
679 CurNode =
getCN(CurNode)->getNextLeafInOrder();
682 CurPiece = &
getCN(CurNode)->getPiece(0);
689 if (CurPiece != &
getCN(CurNode)->getPiece(
getCN(CurNode)->getNumPieces()-1)) {
697 CurNode =
getCN(CurNode)->getNextLeafInOrder();
698 while (CurNode &&
getCN(CurNode)->getNumPieces() == 0);
701 CurPiece = &
getCN(CurNode)->getPiece(0);
712 return static_cast<RopePieceBTreeNode*
>(
P);
716 Root =
new RopePieceBTreeLeaf();
719 assert(RHS.
empty() &&
"Can't copy non-empty tree yet");
720 Root =
new RopePieceBTreeLeaf();
731 if (RopePieceBTreeLeaf *Leaf = dyn_cast<RopePieceBTreeLeaf>(
getRoot(Root)))
735 Root =
new RopePieceBTreeLeaf();
741 if (RopePieceBTreeNode *RHS =
getRoot(Root)->split(Offset))
742 Root =
new RopePieceBTreeInterior(
getRoot(Root), RHS);
745 if (RopePieceBTreeNode *RHS =
getRoot(Root)->
insert(Offset, R))
746 Root =
new RopePieceBTreeInterior(
getRoot(Root), RHS);
751 if (RopePieceBTreeNode *RHS =
getRoot(Root)->split(Offset))
752 Root =
new RopePieceBTreeInterior(
getRoot(Root), RHS);
755 getRoot(Root)->erase(Offset, NumBytes);
766 RopePiece RewriteRope::MakeRopeString(
const char *Start,
const char *
End) {
767 unsigned Len = End-Start;
768 assert(Len &&
"Zero length RopePiece is invalid!");
771 if (AllocOffs+Len <= AllocChunkSize) {
772 memcpy(AllocBuffer->Data+AllocOffs, Start, Len);
774 return RopePiece(AllocBuffer, AllocOffs-Len, AllocOffs);
779 if (Len > AllocChunkSize) {
784 memcpy(Res->Data, Start, End-Start);
795 memcpy(Res->
Data, Start, Len);
void insert(unsigned Offset, const RopePiece &R)
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
void erase(unsigned Offset, unsigned NumBytes)
static RopePieceBTreeNode * getRoot(void *P)
ast_type_traits::DynTypedNode Node
static bool classof(const OMPClause *T)
static const RopePieceBTreeLeaf * getCN(const void *P)