1193326Sed//===--- PPCaching.cpp - Handle caching lexed tokens ----------------------===//
2193326Sed//
3193326Sed//                     The LLVM Compiler Infrastructure
4193326Sed//
5193326Sed// This file is distributed under the University of Illinois Open Source
6193326Sed// License. See LICENSE.TXT for details.
7193326Sed//
8193326Sed//===----------------------------------------------------------------------===//
9193326Sed//
10193326Sed// This file implements pieces of the Preprocessor interface that manage the
11193326Sed// caching of lexed tokens.
12193326Sed//
13193326Sed//===----------------------------------------------------------------------===//
14193326Sed
15193326Sed#include "clang/Lex/Preprocessor.h"
16193326Sedusing namespace clang;
17193326Sed
18193326Sed/// EnableBacktrackAtThisPos - From the point that this method is called, and
19193326Sed/// until CommitBacktrackedTokens() or Backtrack() is called, the Preprocessor
20193326Sed/// keeps track of the lexed tokens so that a subsequent Backtrack() call will
21193326Sed/// make the Preprocessor re-lex the same tokens.
22193326Sed///
23193326Sed/// Nested backtracks are allowed, meaning that EnableBacktrackAtThisPos can
24193326Sed/// be called multiple times and CommitBacktrackedTokens/Backtrack calls will
25193326Sed/// be combined with the EnableBacktrackAtThisPos calls in reverse order.
26193326Sedvoid Preprocessor::EnableBacktrackAtThisPos() {
27193326Sed  BacktrackPositions.push_back(CachedLexPos);
28193326Sed  EnterCachingLexMode();
29193326Sed}
30193326Sed
31193326Sed/// CommitBacktrackedTokens - Disable the last EnableBacktrackAtThisPos call.
32193326Sedvoid Preprocessor::CommitBacktrackedTokens() {
33193326Sed  assert(!BacktrackPositions.empty()
34193326Sed         && "EnableBacktrackAtThisPos was not called!");
35193326Sed  BacktrackPositions.pop_back();
36193326Sed}
37193326Sed
38193326Sed/// Backtrack - Make Preprocessor re-lex the tokens that were lexed since
39198092Srdivacky/// EnableBacktrackAtThisPos() was previously called.
40193326Sedvoid Preprocessor::Backtrack() {
41193326Sed  assert(!BacktrackPositions.empty()
42193326Sed         && "EnableBacktrackAtThisPos was not called!");
43193326Sed  CachedLexPos = BacktrackPositions.back();
44193326Sed  BacktrackPositions.pop_back();
45235633Sdim  recomputeCurLexerKind();
46193326Sed}
47193326Sed
48193326Sedvoid Preprocessor::CachingLex(Token &Result) {
49210299Sed  if (!InCachingLexMode())
50210299Sed    return;
51210299Sed
52193326Sed  if (CachedLexPos < CachedTokens.size()) {
53193326Sed    Result = CachedTokens[CachedLexPos++];
54193326Sed    return;
55193326Sed  }
56193326Sed
57193326Sed  ExitCachingLexMode();
58193326Sed  Lex(Result);
59193326Sed
60235633Sdim  if (isBacktrackEnabled()) {
61235633Sdim    // Cache the lexed token.
62235633Sdim    EnterCachingLexMode();
63235633Sdim    CachedTokens.push_back(Result);
64235633Sdim    ++CachedLexPos;
65235633Sdim    return;
66235633Sdim  }
67235633Sdim
68235633Sdim  if (CachedLexPos < CachedTokens.size()) {
69235633Sdim    EnterCachingLexMode();
70235633Sdim  } else {
71193326Sed    // All cached tokens were consumed.
72193326Sed    CachedTokens.clear();
73193326Sed    CachedLexPos = 0;
74193326Sed  }
75193326Sed}
76193326Sed
77193326Sedvoid Preprocessor::EnterCachingLexMode() {
78193326Sed  if (InCachingLexMode())
79193326Sed    return;
80193326Sed
81193326Sed  PushIncludeMacroStack();
82235633Sdim  CurLexerKind = CLK_CachingLexer;
83193326Sed}
84193326Sed
85193326Sed
86193326Sedconst Token &Preprocessor::PeekAhead(unsigned N) {
87193326Sed  assert(CachedLexPos + N > CachedTokens.size() && "Confused caching.");
88193326Sed  ExitCachingLexMode();
89193326Sed  for (unsigned C = CachedLexPos + N - CachedTokens.size(); C > 0; --C) {
90193326Sed    CachedTokens.push_back(Token());
91193326Sed    Lex(CachedTokens.back());
92193326Sed  }
93193326Sed  EnterCachingLexMode();
94193326Sed  return CachedTokens.back();
95193326Sed}
96193326Sed
97193326Sedvoid Preprocessor::AnnotatePreviousCachedTokens(const Token &Tok) {
98193326Sed  assert(Tok.isAnnotation() && "Expected annotation token");
99193326Sed  assert(CachedLexPos != 0 && "Expected to have some cached tokens");
100203955Srdivacky  assert(CachedTokens[CachedLexPos-1].getLastLoc() == Tok.getAnnotationEndLoc()
101193326Sed         && "The annotation should be until the most recent cached token");
102193326Sed
103193326Sed  // Start from the end of the cached tokens list and look for the token
104193326Sed  // that is the beginning of the annotation token.
105193326Sed  for (CachedTokensTy::size_type i = CachedLexPos; i != 0; --i) {
106193326Sed    CachedTokensTy::iterator AnnotBegin = CachedTokens.begin() + i-1;
107193326Sed    if (AnnotBegin->getLocation() == Tok.getLocation()) {
108193326Sed      assert((BacktrackPositions.empty() || BacktrackPositions.back() < i) &&
109193326Sed             "The backtrack pos points inside the annotated tokens!");
110193326Sed      // Replace the cached tokens with the single annotation token.
111198092Srdivacky      if (i < CachedLexPos)
112198092Srdivacky        CachedTokens.erase(AnnotBegin + 1, CachedTokens.begin() + CachedLexPos);
113193326Sed      *AnnotBegin = Tok;
114193326Sed      CachedLexPos = i;
115193326Sed      return;
116193326Sed    }
117193326Sed  }
118193326Sed}
119