Allow nested backtracks.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@55204 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Lex/PPCaching.cpp b/lib/Lex/PPCaching.cpp
index 794e9c4..e69eac6 100644
--- a/lib/Lex/PPCaching.cpp
+++ b/lib/Lex/PPCaching.cpp
@@ -15,6 +15,38 @@
 #include "clang/Lex/Preprocessor.h"
 using namespace clang;
 
+/// EnableBacktrackAtThisPos - From the point that this method is called, and

+/// until DisableBacktrack() or Backtrack() is called, the Preprocessor keeps

+/// track of the lexed tokens so that a subsequent Backtrack() call will make

+/// the Preprocessor re-lex the same tokens.

+///

+/// Nested backtracks are allowed, meaning that EnableBacktrackAtThisPos can

+/// be called multiple times and DisableBacktrack/Backtrack calls will be

+/// combined with the EnableBacktrackAtThisPos calls in reverse order.

+void Preprocessor::EnableBacktrackAtThisPos() {

+  CacheTokens = true;

+  BacktrackPositions.push_back(CachedLexPos);

+  EnterCachingLexMode();

+}

+
+/// DisableBacktrack - Disable the last EnableBacktrackAtThisPos() call.

+void Preprocessor::DisableBacktrack() {

+  assert(!BacktrackPositions.empty()

+         && "EnableBacktrackAtThisPos was not called!");

+  BacktrackPositions.pop_back();

+  CacheTokens = !BacktrackPositions.empty();

+}

+

+/// Backtrack - Make Preprocessor re-lex the tokens that were lexed since

+/// EnableBacktrackAtThisPos() was previously called. 

+void Preprocessor::Backtrack() {

+  assert(!BacktrackPositions.empty()

+         && "EnableBacktrackAtThisPos was not called!");

+  CachedLexPos = BacktrackPositions.back();

+  BacktrackPositions.pop_back();

+  CacheTokens = !BacktrackPositions.empty();

+}

+
 void Preprocessor::CachingLex(Token &Result) {
   if (CachedLexPos < CachedTokens.size()) {
     Result = CachedTokens[CachedLexPos++];