mirror of
https://github.com/llvm/llvm-project.git
synced 2025-05-03 06:16:06 +00:00

Token now has a class of kinds for "literals", which include numeric constants, strings, etc. These tokens can optionally have a pointer to the start of the token in the lexer buffer. This makes it faster to get spelling and do other gymnastics, because we don't have to go through source locations. This change is performance neutral, but will make other changes more feasible down the road. llvm-svn: 63028
114 lines
3.8 KiB
C++
114 lines
3.8 KiB
C++
//===--- PPCaching.cpp - Handle caching lexed tokens ----------------------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file implements pieces of the Preprocessor interface that manage the
|
|
// caching of lexed tokens.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "clang/Lex/Preprocessor.h"
|
|
using namespace clang;
|
|
|
|
/// EnableBacktrackAtThisPos - From the point that this method is called, and
|
|
/// until CommitBacktrackedTokens() 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 CommitBacktrackedTokens/Backtrack calls will
|
|
/// be combined with the EnableBacktrackAtThisPos calls in reverse order.
|
|
void Preprocessor::EnableBacktrackAtThisPos() {
|
|
BacktrackPositions.push_back(CachedLexPos);
|
|
EnterCachingLexMode();
|
|
}
|
|
|
|
/// CommitBacktrackedTokens - Disable the last EnableBacktrackAtThisPos call.
|
|
void Preprocessor::CommitBacktrackedTokens() {
|
|
assert(!BacktrackPositions.empty()
|
|
&& "EnableBacktrackAtThisPos was not called!");
|
|
BacktrackPositions.pop_back();
|
|
}
|
|
|
|
/// 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();
|
|
}
|
|
|
|
void Preprocessor::CachingLex(Token &Result) {
|
|
if (CachedLexPos < CachedTokens.size()) {
|
|
Result = CachedTokens[CachedLexPos++];
|
|
return;
|
|
}
|
|
|
|
ExitCachingLexMode();
|
|
Lex(Result);
|
|
|
|
if (!isBacktrackEnabled()) {
|
|
// All cached tokens were consumed.
|
|
CachedTokens.clear();
|
|
CachedLexPos = 0;
|
|
return;
|
|
}
|
|
|
|
// We should cache the lexed token.
|
|
|
|
EnterCachingLexMode();
|
|
if (Result.isNot(tok::eof)) {
|
|
CachedTokens.push_back(Result);
|
|
++CachedLexPos;
|
|
}
|
|
}
|
|
|
|
void Preprocessor::EnterCachingLexMode() {
|
|
if (InCachingLexMode())
|
|
return;
|
|
|
|
PushIncludeMacroStack();
|
|
}
|
|
|
|
|
|
const Token &Preprocessor::PeekAhead(unsigned N) {
|
|
assert(CachedLexPos + N > CachedTokens.size() && "Confused caching.");
|
|
ExitCachingLexMode();
|
|
for (unsigned C = CachedLexPos + N - CachedTokens.size(); C > 0; --C) {
|
|
CachedTokens.push_back(Token());
|
|
Lex(CachedTokens.back());
|
|
}
|
|
EnterCachingLexMode();
|
|
return CachedTokens.back();
|
|
}
|
|
|
|
void Preprocessor::AnnotatePreviousCachedTokens(const Token &Tok) {
|
|
assert(Tok.isAnnotation() && "Expected annotation token");
|
|
assert(CachedLexPos != 0 && "Expected to have some cached tokens");
|
|
assert(CachedTokens[CachedLexPos-1].getLocation() == Tok.getAnnotationEndLoc()
|
|
&& "The annotation should be until the most recent cached token");
|
|
|
|
// Start from the end of the cached tokens list and look for the token
|
|
// that is the beginning of the annotation token.
|
|
for (CachedTokensTy::size_type i = CachedLexPos; i != 0; --i) {
|
|
CachedTokensTy::iterator AnnotBegin = CachedTokens.begin() + i-1;
|
|
if (AnnotBegin->getLocation() == Tok.getLocation()) {
|
|
assert((BacktrackPositions.empty() || BacktrackPositions.back() < i) &&
|
|
"The backtrack pos points inside the annotated tokens!");
|
|
// Replace the cached tokens with the single annotation token.
|
|
CachedTokens.erase(AnnotBegin + 1, CachedTokens.begin() + CachedLexPos);
|
|
*AnnotBegin = Tok;
|
|
CachedLexPos = i;
|
|
return;
|
|
}
|
|
}
|
|
|
|
assert(0&&"Didn't find the first token represented by the annotation token!");
|
|
}
|