2008-11-12 21:37:15 +00:00
|
|
|
//===--- PTHLexer.cpp - Lex from a token stream ---------------------------===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file implements the PTHLexer interface.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "clang/Lex/PTHLexer.h"
|
|
|
|
#include "clang/Lex/Preprocessor.h"
|
|
|
|
#include "clang/Basic/TokenKinds.h"
|
|
|
|
using namespace clang;
|
|
|
|
|
|
|
|
PTHLexer::PTHLexer(Preprocessor& pp, SourceLocation fileloc,
|
2008-11-20 01:29:45 +00:00
|
|
|
const Token *TokArray, unsigned NumTokens)
|
|
|
|
: PreprocessorLexer(&pp, fileloc),
|
|
|
|
Tokens(TokArray),
|
2008-11-20 16:32:22 +00:00
|
|
|
LastTokenIdx(NumTokens - 1),
|
|
|
|
CurTokenIdx(0) {
|
2008-11-12 21:37:15 +00:00
|
|
|
|
2008-11-20 07:58:05 +00:00
|
|
|
assert(NumTokens >= 1);
|
2008-11-20 16:32:22 +00:00
|
|
|
assert(Tokens[LastTokenIdx].is(tok::eof));
|
2008-11-12 21:37:15 +00:00
|
|
|
}
|
|
|
|
|
2008-11-20 19:49:00 +00:00
|
|
|
Token PTHLexer::GetToken() {
|
|
|
|
Token Tok = Tokens[CurTokenIdx];
|
|
|
|
|
|
|
|
// If we are in raw mode, zero out identifier pointers. This is
|
|
|
|
// needed for 'pragma poison'. Note that this requires that the Preprocessor
|
|
|
|
// can go back to the original source when it calls getSpelling().
|
|
|
|
if (LexingRawMode && Tok.is(tok::identifier))
|
|
|
|
Tok.setIdentifierInfo(0);
|
|
|
|
|
|
|
|
return Tok;
|
|
|
|
}
|
|
|
|
|
2008-11-12 21:37:15 +00:00
|
|
|
void PTHLexer::Lex(Token& Tok) {
|
2008-11-20 07:58:05 +00:00
|
|
|
LexNextToken:
|
2008-11-21 00:58:35 +00:00
|
|
|
Tok = GetToken();
|
|
|
|
|
2008-11-20 16:32:22 +00:00
|
|
|
if (AtLastToken()) {
|
2008-11-21 00:58:35 +00:00
|
|
|
Preprocessor *PPCache = PP;
|
|
|
|
|
|
|
|
if (LexEndOfFile(Tok))
|
2008-11-20 07:58:05 +00:00
|
|
|
return;
|
2008-11-12 21:37:15 +00:00
|
|
|
|
2008-11-21 00:58:35 +00:00
|
|
|
assert(PPCache && "Raw buffer::LexEndOfFile should return a token");
|
|
|
|
return PPCache->Lex(Tok);
|
|
|
|
}
|
2008-11-12 21:37:15 +00:00
|
|
|
|
2008-11-20 07:58:05 +00:00
|
|
|
// Don't advance to the next token yet. Check if we are at the
|
|
|
|
// start of a new line and we're processing a directive. If so, we
|
|
|
|
// consume this token twice, once as an tok::eom.
|
|
|
|
if (Tok.isAtStartOfLine() && ParsingPreprocessorDirective) {
|
|
|
|
ParsingPreprocessorDirective = false;
|
|
|
|
Tok.setKind(tok::eom);
|
2008-11-12 21:37:15 +00:00
|
|
|
MIOpt.ReadToken();
|
|
|
|
return;
|
|
|
|
}
|
2008-11-20 07:58:05 +00:00
|
|
|
|
|
|
|
// Advance to the next token.
|
2008-11-20 16:32:22 +00:00
|
|
|
AdvanceToken();
|
2008-11-20 07:58:05 +00:00
|
|
|
|
|
|
|
if (Tok.is(tok::hash)) {
|
|
|
|
if (Tok.isAtStartOfLine() && !LexingRawMode) {
|
|
|
|
PP->HandleDirective(Tok);
|
2008-11-12 21:37:15 +00:00
|
|
|
|
2008-11-20 07:58:05 +00:00
|
|
|
if (PP->isCurrentLexer(this))
|
|
|
|
goto LexNextToken;
|
|
|
|
|
|
|
|
return PP->Lex(Tok);
|
|
|
|
}
|
2008-11-12 21:37:15 +00:00
|
|
|
}
|
2008-11-20 07:58:05 +00:00
|
|
|
|
2008-11-12 21:37:15 +00:00
|
|
|
MIOpt.ReadToken();
|
2008-11-20 07:58:05 +00:00
|
|
|
|
|
|
|
if (Tok.is(tok::identifier)) {
|
|
|
|
if (LexingRawMode) return;
|
|
|
|
return PP->HandleIdentifier(Tok);
|
|
|
|
}
|
2008-11-12 21:37:15 +00:00
|
|
|
}
|
|
|
|
|
2008-11-21 00:58:35 +00:00
|
|
|
bool PTHLexer::LexEndOfFile(Token &Tok) {
|
|
|
|
|
|
|
|
if (ParsingPreprocessorDirective) {
|
|
|
|
ParsingPreprocessorDirective = false;
|
|
|
|
Tok.setKind(tok::eom);
|
|
|
|
MIOpt.ReadToken();
|
|
|
|
return true; // Have a token.
|
|
|
|
}
|
|
|
|
|
|
|
|
if (LexingRawMode) {
|
|
|
|
MIOpt.ReadToken();
|
|
|
|
return true; // Have an eof token.
|
|
|
|
}
|
|
|
|
|
|
|
|
// FIXME: Issue diagnostics similar to Lexer.
|
|
|
|
return PP->HandleEndOfFile(Tok, false);
|
|
|
|
}
|
|
|
|
|
2008-11-12 21:37:15 +00:00
|
|
|
void PTHLexer::setEOF(Token& Tok) {
|
2008-11-20 16:32:22 +00:00
|
|
|
Tok = Tokens[LastTokenIdx];
|
2008-11-12 21:37:15 +00:00
|
|
|
}
|
2008-11-19 22:21:33 +00:00
|
|
|
|
|
|
|
void PTHLexer::DiscardToEndOfLine() {
|
|
|
|
assert(ParsingPreprocessorDirective && ParsingFilename == false &&
|
|
|
|
"Must be in a preprocessing directive!");
|
2008-11-20 01:16:50 +00:00
|
|
|
|
|
|
|
// Already at end-of-file?
|
2008-11-20 16:32:22 +00:00
|
|
|
if (AtLastToken())
|
2008-11-20 01:16:50 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
// Find the first token that is not the start of the *current* line.
|
2008-11-20 16:32:22 +00:00
|
|
|
for (AdvanceToken(); !AtLastToken(); AdvanceToken())
|
|
|
|
if (GetToken().isAtStartOfLine())
|
2008-11-20 01:16:50 +00:00
|
|
|
return;
|
2008-11-19 22:21:33 +00:00
|
|
|
}
|