16 #include "llvm/Support/Casting.h" 20 using namespace clang;
46 static SourceDelta
get(
unsigned Loc,
int D) {
59 DeltaTreeNode *LHS, *RHS;
64 friend class DeltaTreeInteriorNode;
70 enum { WidthFactor = 8 };
73 SourceDelta Values[2*WidthFactor-1];
77 unsigned char NumValuesUsed = 0;
88 DeltaTreeNode(
bool isLeaf =
true) : IsLeaf(isLeaf) {}
90 bool isLeaf()
const {
return IsLeaf; }
91 int getFullDelta()
const {
return FullDelta; }
92 bool isFull()
const {
return NumValuesUsed == 2*WidthFactor-1; }
94 unsigned getNumValuesUsed()
const {
return NumValuesUsed; }
96 const SourceDelta &
getValue(
unsigned i)
const {
97 assert(i < NumValuesUsed &&
"Invalid value #");
102 assert(i < NumValuesUsed &&
"Invalid value #");
110 bool DoInsertion(
unsigned FileIndex,
int Delta, InsertResult *InsertRes);
112 void DoSplit(InsertResult &InsertRes);
117 void RecomputeFullDeltaLocally();
124 class DeltaTreeInteriorNode :
public DeltaTreeNode {
125 friend class DeltaTreeNode;
127 DeltaTreeNode *Children[2*WidthFactor];
129 ~DeltaTreeInteriorNode() {
130 for (
unsigned i = 0, e = NumValuesUsed+1; i != e; ++i)
131 Children[i]->Destroy();
135 DeltaTreeInteriorNode() : DeltaTreeNode(
false ) {}
137 DeltaTreeInteriorNode(
const InsertResult &IR)
138 : DeltaTreeNode(
false ) {
139 Children[0] = IR.LHS;
140 Children[1] = IR.RHS;
141 Values[0] = IR.Split;
142 FullDelta = IR.LHS->getFullDelta()+IR.RHS->getFullDelta()+IR.Split.Delta;
146 const DeltaTreeNode *getChild(
unsigned i)
const {
147 assert(i < getNumValuesUsed()+1 &&
"Invalid child");
151 DeltaTreeNode *getChild(
unsigned i) {
152 assert(i < getNumValuesUsed()+1 &&
"Invalid child");
156 static bool classof(
const DeltaTreeNode *N) {
return !N->isLeaf(); }
162 void DeltaTreeNode::Destroy() {
166 delete cast<DeltaTreeInteriorNode>(
this);
171 void DeltaTreeNode::RecomputeFullDeltaLocally() {
172 int NewFullDelta = 0;
173 for (
unsigned i = 0, e = getNumValuesUsed(); i != e; ++i)
174 NewFullDelta += Values[i].Delta;
175 if (
auto *IN = dyn_cast<DeltaTreeInteriorNode>(
this))
176 for (
unsigned i = 0, e = getNumValuesUsed()+1; i != e; ++i)
177 NewFullDelta += IN->getChild(i)->getFullDelta();
178 FullDelta = NewFullDelta;
185 bool DeltaTreeNode::DoInsertion(
unsigned FileIndex,
int Delta,
186 InsertResult *InsertRes) {
191 unsigned i = 0, e = getNumValuesUsed();
192 while (i != e && FileIndex >
getValue(i).FileLoc)
197 if (i != e &&
getValue(i).FileLoc == FileIndex) {
202 Values[i].Delta += Delta;
213 memmove(&Values[i+1], &Values[i],
sizeof(Values[0])*(e-i));
214 Values[i] = SourceDelta::get(FileIndex, Delta);
221 assert(InsertRes &&
"No result location specified");
224 if (InsertRes->Split.FileLoc > FileIndex)
225 InsertRes->LHS->DoInsertion(FileIndex, Delta,
nullptr );
227 InsertRes->RHS->DoInsertion(FileIndex, Delta,
nullptr );
232 auto *IN = cast<DeltaTreeInteriorNode>(
this);
233 if (!IN->Children[i]->DoInsertion(FileIndex, Delta, InsertRes))
243 memmove(&IN->Children[i+2], &IN->Children[i+1],
244 (e-i)*
sizeof(IN->Children[0]));
245 IN->Children[i] = InsertRes->LHS;
246 IN->Children[i+1] = InsertRes->RHS;
249 memmove(&Values[i+1], &Values[i], (e-i)*
sizeof(Values[0]));
250 Values[i] = InsertRes->Split;
258 IN->Children[i] = InsertRes->LHS;
259 DeltaTreeNode *SubRHS = InsertRes->RHS;
260 SourceDelta SubSplit = InsertRes->Split;
266 DeltaTreeInteriorNode *InsertSide;
267 if (SubSplit.FileLoc < InsertRes->Split.FileLoc)
268 InsertSide = cast<DeltaTreeInteriorNode>(InsertRes->LHS);
270 InsertSide = cast<DeltaTreeInteriorNode>(InsertRes->RHS);
276 i = 0; e = InsertSide->getNumValuesUsed();
277 while (i != e && SubSplit.FileLoc > InsertSide->getValue(i).FileLoc)
283 memmove(&InsertSide->Children[i+2], &InsertSide->Children[i+1],
284 (e-i)*
sizeof(IN->Children[0]));
285 InsertSide->Children[i+1] = SubRHS;
288 memmove(&InsertSide->Values[i+1], &InsertSide->Values[i],
289 (e-i)*
sizeof(Values[0]));
290 InsertSide->Values[i] = SubSplit;
291 ++InsertSide->NumValuesUsed;
292 InsertSide->FullDelta += SubSplit.Delta + SubRHS->getFullDelta();
299 void DeltaTreeNode::DoSplit(InsertResult &InsertRes) {
300 assert(isFull() &&
"Why split a non-full node?");
308 DeltaTreeNode *NewNode;
309 if (
auto *IN = dyn_cast<DeltaTreeInteriorNode>(
this)) {
312 DeltaTreeInteriorNode *New =
new DeltaTreeInteriorNode();
313 memcpy(&New->Children[0], &IN->Children[WidthFactor],
314 WidthFactor*
sizeof(IN->Children[0]));
318 NewNode =
new DeltaTreeNode();
322 memcpy(&NewNode->Values[0], &Values[WidthFactor],
323 (WidthFactor-1)*
sizeof(Values[0]));
326 NewNode->NumValuesUsed = NumValuesUsed = WidthFactor-1;
329 NewNode->RecomputeFullDeltaLocally();
330 RecomputeFullDeltaLocally();
332 InsertRes.LHS =
this;
333 InsertRes.RHS = NewNode;
334 InsertRes.Split = Values[WidthFactor-1];
346 static void VerifyTree(
const DeltaTreeNode *N) {
347 const auto *IN = dyn_cast<DeltaTreeInteriorNode>(N);
352 for (
unsigned i = 0, e = N->getNumValuesUsed(); i != e; ++i) {
354 assert(N->getValue(i-1).FileLoc < N->getValue(i).FileLoc);
355 FullDelta += N->getValue(i).Delta;
357 assert(FullDelta == N->getFullDelta());
364 for (
unsigned i = 0, e = IN->getNumValuesUsed(); i != e; ++i) {
365 const SourceDelta &IVal = N->getValue(i);
366 const DeltaTreeNode *IChild = IN->getChild(i);
368 assert(IN->getValue(i-1).FileLoc < IVal.FileLoc);
369 FullDelta += IVal.Delta;
370 FullDelta += IChild->getFullDelta();
373 assert(IChild->getValue(IChild->getNumValuesUsed()-1).FileLoc <
377 assert(IN->getChild(i+1)->getValue(0).FileLoc > IVal.FileLoc);
381 FullDelta += IN->getChild(IN->getNumValuesUsed())->getFullDelta();
383 assert(FullDelta == N->getFullDelta());
385 #endif // VERIFY_TREE 388 return (DeltaTreeNode*)Root;
392 Root =
new DeltaTreeNode();
397 assert(
getRoot(RHS.Root)->getNumValuesUsed() == 0 &&
398 "Can only copy empty tree");
399 Root =
new DeltaTreeNode();
419 unsigned NumValsGreater = 0;
420 for (
unsigned e = Node->getNumValuesUsed(); NumValsGreater != e;
422 const SourceDelta &Val = Node->getValue(NumValsGreater);
424 if (Val.FileLoc >= FileIndex)
431 const auto *IN = dyn_cast<DeltaTreeInteriorNode>(
Node);
436 for (
unsigned i = 0; i != NumValsGreater; ++i)
437 Result += IN->getChild(i)->getFullDelta();
442 if (NumValsGreater != Node->getNumValuesUsed() &&
443 Node->getValue(NumValsGreater).FileLoc == FileIndex)
444 return Result+IN->getChild(NumValsGreater)->getFullDelta();
448 Node = IN->getChild(NumValsGreater);
457 assert(Delta &&
"Adding a noop?");
458 DeltaTreeNode *MyRoot =
getRoot(Root);
460 DeltaTreeNode::InsertResult InsertRes;
461 if (MyRoot->DoInsertion(FileIndex, Delta, &InsertRes)) {
462 Root = MyRoot =
new DeltaTreeInteriorNode(InsertRes);
void AddDelta(unsigned FileIndex, int Delta)
AddDelta - When a change is made that shifts around the text buffer, this method is used to record th...
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
static DeltaTreeNode * getRoot(void *Root)
static SVal getValue(SVal val, SValBuilder &svalBuilder)
int getDeltaAt(unsigned FileIndex) const
getDeltaAt - Return the accumulated delta at the specified file offset.
The result type of a method or function.
DeltaTree - a multiway search tree (BTree) structure with some fancy features.
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
ast_type_traits::DynTypedNode Node
Dataflow Directional Tag Classes.
static bool classof(const OMPClause *T)