PTHLexer.cpp revision d6f53dc4951aace69014619761760addac9e59ec
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 LastToken(NumTokens - 1), 24 CurToken(0) { 25 26 assert(NumTokens >= 1); 27 assert(Tokens[LastToken].is(tok::eof)); 28} 29 30void PTHLexer::Lex(Token& Tok) { 31LexNextToken: 32 if (CurToken == LastToken) { 33 if (ParsingPreprocessorDirective) { 34 ParsingPreprocessorDirective = false; 35 Tok = Tokens[LastToken]; 36 Tok.setKind(tok::eom); 37 MIOpt.ReadToken(); 38 return; 39 } 40 41 assert(!LexingRawMode && "PTHLexer cannot lex in raw mode."); 42 43 // FIXME: Issue diagnostics similar to Lexer. 44 PP->HandleEndOfFile(Tok, false); 45 return; 46 } 47 48 Tok = Tokens[CurToken]; 49 50 // Don't advance to the next token yet. Check if we are at the 51 // start of a new line and we're processing a directive. If so, we 52 // consume this token twice, once as an tok::eom. 53 if (Tok.isAtStartOfLine() && ParsingPreprocessorDirective) { 54 ParsingPreprocessorDirective = false; 55 Tok.setKind(tok::eom); 56 MIOpt.ReadToken(); 57 return; 58 } 59 60 // Advance to the next token. 61 ++CurToken; 62 63 if (Tok.is(tok::hash)) { 64 if (Tok.isAtStartOfLine() && !LexingRawMode) { 65 PP->HandleDirective(Tok); 66 67 if (PP->isCurrentLexer(this)) 68 goto LexNextToken; 69 70 return PP->Lex(Tok); 71 } 72 } 73 74 MIOpt.ReadToken(); 75 76 if (Tok.is(tok::identifier)) { 77 if (LexingRawMode) return; 78 return PP->HandleIdentifier(Tok); 79 } 80} 81 82void PTHLexer::setEOF(Token& Tok) { 83 Tok = Tokens[LastToken]; 84} 85 86void PTHLexer::DiscardToEndOfLine() { 87 assert(ParsingPreprocessorDirective && ParsingFilename == false && 88 "Must be in a preprocessing directive!"); 89 90 // Already at end-of-file? 91 if (CurToken == LastToken) 92 return; 93 94 // Find the first token that is not the start of the *current* line. 95 for ( ++CurToken; CurToken != LastToken ; ++CurToken ) 96 if (Tokens[CurToken].isAtStartOfLine()) 97 return; 98} 99 100unsigned PTHLexer::isNextPPTokenLParen() { 101 if (CurToken == LastToken) 102 return 2; 103 104 return Tokens[CurToken].is(tok::l_paren); 105} 106 107