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