| //===--- 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) |
| : PreprocessorLexer(&pp, fileloc), CurTokenIdx(0) {} |
| |
| 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; |
| } |
| |
| void PTHLexer::Lex(Token& Tok) { |
| LexNextToken: |
| Tok = GetToken(); |
| |
| if (AtLastToken()) { |
| Preprocessor *PPCache = PP; |
| |
| if (LexEndOfFile(Tok)) |
| return; |
| |
| assert(PPCache && "Raw buffer::LexEndOfFile should return a token"); |
| return PPCache->Lex(Tok); |
| } |
| |
| // 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); |
| MIOpt.ReadToken(); |
| return; |
| } |
| |
| // Advance to the next token. |
| AdvanceToken(); |
| |
| if (Tok.is(tok::hash)) { |
| if (Tok.isAtStartOfLine() && !LexingRawMode) { |
| PP->HandleDirective(Tok); |
| |
| if (PP->isCurrentLexer(this)) |
| goto LexNextToken; |
| |
| return PP->Lex(Tok); |
| } |
| } |
| |
| MIOpt.ReadToken(); |
| |
| if (Tok.is(tok::identifier)) { |
| if (LexingRawMode) return; |
| return PP->HandleIdentifier(Tok); |
| } |
| } |
| |
| 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); |
| } |
| |
| void PTHLexer::setEOF(Token& Tok) { |
| assert(!Tokens.empty()); |
| Tok = Tokens[Tokens.size()-1]; |
| } |
| |
| void PTHLexer::DiscardToEndOfLine() { |
| assert(ParsingPreprocessorDirective && ParsingFilename == false && |
| "Must be in a preprocessing directive!"); |
| |
| // Already at end-of-file? |
| if (AtLastToken()) |
| return; |
| |
| // Find the first token that is not the start of the *current* line. |
| Token T; |
| for (Lex(T); !AtLastToken(); Lex(T)) |
| if (GetToken().isAtStartOfLine()) |
| return; |
| } |