]> granicus.if.org Git - clang/commitdiff
Use a non-recursive implementation to reconstruct line breaks.
authorManuel Klimek <klimek@google.com>
Wed, 29 May 2013 15:10:11 +0000 (15:10 +0000)
committerManuel Klimek <klimek@google.com>
Wed, 29 May 2013 15:10:11 +0000 (15:10 +0000)
Now that the TokenAnnotator does not require stack space anymore,
reconstructing the lines has become the limiting factor. This patch
fixes that problem, allowing large files with multiple megabytes of
single unwrapped lines to be formatted.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@182861 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Format/Format.cpp

index 6fc0da58c232687bde1c22fe9b519dd3cfa52727..b6e8079b31a21db0d693b96594a2bdce63a5f6d8 100644 (file)
@@ -949,22 +949,23 @@ private:
   }
 
   void reconstructPath(LineState &State, StateNode *Current) {
-    // FIXME: This recursive implementation limits the possible number
-    // of tokens per line if compiled into a binary with small stack space.
-    // To become more independent of stack frame limitations we would need
-    // to also change the TokenAnnotator.
-    if (Current->Previous == NULL)
-      return;
-    reconstructPath(State, Current->Previous);
-    DEBUG({
-      if (Current->NewLine) {
-        llvm::dbgs() << "Penalty for splitting before "
-                     << Current->Previous->State.NextToken->Tok.getName()
-                     << ": " << Current->Previous->State.NextToken->SplitPenalty
-                     << "\n";
-      }
-    });
-    addTokenToState(Current->NewLine, false, State);
+    std::deque<StateNode *> Path;
+    // We do not need a break before the initial token.
+    while (Current->Previous) {
+      Path.push_front(Current);
+      Current = Current->Previous;
+    }
+    for (std::deque<StateNode *>::iterator I = Path.begin(), E = Path.end();
+         I != E; ++I) {
+      DEBUG({
+        if ((*I)->NewLine) {
+          llvm::dbgs() << "Penalty for splitting before "
+                       << (*I)->Previous->State.NextToken->Tok.getName() << ": "
+                       << (*I)->Previous->State.NextToken->SplitPenalty << "\n";
+        }
+      });
+      addTokenToState((*I)->NewLine, false, State);
+    }
   }
 
   /// \brief Add the following state to the analysis queue \c Queue.