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