PTHLexer.cpp revision cd4e2aecde5bb7810715d5d5a88ac63ce7946f34
1//===--- PTHLexer.cpp - Lex from a token stream ---------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements the PTHLexer interface. 11// 12//===----------------------------------------------------------------------===// 13 14#include "clang/Lex/PTHLexer.h" 15#include "clang/Lex/Preprocessor.h" 16#include "clang/Basic/TokenKinds.h" 17using namespace clang; 18 19PTHLexer::PTHLexer(Preprocessor& pp, SourceLocation fileloc, 20 const Token *TokArray, unsigned NumTokens) 21 : PreprocessorLexer(&pp, fileloc), 22 Tokens(TokArray), 23 LastTokenIdx(NumTokens - 1), 24 CurTokenIdx(0) { 25 26 assert(NumTokens >= 1); 27 assert(Tokens[LastTokenIdx].is(tok::eof)); 28} 29 30Token PTHLexer::GetToken() { 31 Token Tok = Tokens[CurTokenIdx]; 32 33 // If we are in raw mode, zero out identifier pointers. This is 34 // needed for 'pragma poison'. Note that this requires that the Preprocessor 35 // can go back to the original source when it calls getSpelling(). 36 if (LexingRawMode && Tok.is(tok::identifier)) 37 Tok.setIdentifierInfo(0); 38 39 return Tok; 40} 41 42void PTHLexer::Lex(Token& Tok) { 43LexNextToken: 44 Tok = GetToken(); 45 46 if (AtLastToken()) { 47 Preprocessor *PPCache = PP; 48 49 if (LexEndOfFile(Tok)) 50 return; 51 52 assert(PPCache && "Raw buffer::LexEndOfFile should return a token"); 53 return PPCache->Lex(Tok); 54 } 55 56 // Don't advance to the next token yet. Check if we are at the 57 // start of a new line and we're processing a directive. If so, we 58 // consume this token twice, once as an tok::eom. 59 if (Tok.isAtStartOfLine() && ParsingPreprocessorDirective) { 60 ParsingPreprocessorDirective = false; 61 Tok.setKind(tok::eom); 62 MIOpt.ReadToken(); 63 return; 64 } 65 66 // Advance to the next token. 67 AdvanceToken(); 68 69 if (Tok.is(tok::hash)) { 70 if (Tok.isAtStartOfLine() && !LexingRawMode) { 71 PP->HandleDirective(Tok); 72 73 if (PP->isCurrentLexer(this)) 74 goto LexNextToken; 75 76 return PP->Lex(Tok); 77 } 78 } 79 80 MIOpt.ReadToken(); 81 82 if (Tok.is(tok::identifier)) { 83 if (LexingRawMode) return; 84 return PP->HandleIdentifier(Tok); 85 } 86} 87 88bool PTHLexer::LexEndOfFile(Token &Tok) { 89 90 if (ParsingPreprocessorDirective) { 91 ParsingPreprocessorDirective = false; 92 Tok.setKind(tok::eom); 93 MIOpt.ReadToken(); 94 return true; // Have a token. 95 } 96 97 if (LexingRawMode) { 98 MIOpt.ReadToken(); 99 return true; // Have an eof token. 100 } 101 102 // FIXME: Issue diagnostics similar to Lexer. 103 return PP->HandleEndOfFile(Tok, false); 104} 105 106void PTHLexer::setEOF(Token& Tok) { 107 Tok = Tokens[LastTokenIdx]; 108} 109 110void PTHLexer::DiscardToEndOfLine() { 111 assert(ParsingPreprocessorDirective && ParsingFilename == false && 112 "Must be in a preprocessing directive!"); 113 114 // Already at end-of-file? 115 if (AtLastToken()) 116 return; 117 118 // Find the first token that is not the start of the *current* line. 119 for (AdvanceToken(); !AtLastToken(); AdvanceToken()) 120 if (GetToken().isAtStartOfLine()) 121 return; 122} 123