blob: 21fb9831a4ed32f3412969abc343b40812aef266 [file] [log] [blame]
Ted Kremenek274b2082008-11-12 21:37:15 +00001//===--- 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"
Ted Kremenek274b2082008-11-12 21:37:15 +000016#include "clang/Basic/TokenKinds.h"
Ted Kremenek274b2082008-11-12 21:37:15 +000017using namespace clang;
18
19PTHLexer::PTHLexer(Preprocessor& pp, SourceLocation fileloc,
Ted Kremenek452e3782008-11-20 01:29:45 +000020 const Token *TokArray, unsigned NumTokens)
21 : PreprocessorLexer(&pp, fileloc),
22 Tokens(TokArray),
Ted Kremenek31aba422008-11-20 16:32:22 +000023 LastTokenIdx(NumTokens - 1),
24 CurTokenIdx(0) {
Ted Kremenek274b2082008-11-12 21:37:15 +000025
Ted Kremenekd6f53dc2008-11-20 07:58:05 +000026 assert(NumTokens >= 1);
Ted Kremenek31aba422008-11-20 16:32:22 +000027 assert(Tokens[LastTokenIdx].is(tok::eof));
Ted Kremenek274b2082008-11-12 21:37:15 +000028}
29
Ted Kremenek89d7ee92008-11-20 19:49:00 +000030Token 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
Ted Kremenek274b2082008-11-12 21:37:15 +000042void PTHLexer::Lex(Token& Tok) {
Ted Kremenekd6f53dc2008-11-20 07:58:05 +000043LexNextToken:
Ted Kremenek31aba422008-11-20 16:32:22 +000044 Tok = GetToken();
Ted Kremenek274b2082008-11-12 21:37:15 +000045
Ted Kremenekcd4e2ae2008-11-21 00:58:35 +000046 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
Ted Kremenekd6f53dc2008-11-20 07:58:05 +000056 // 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);
Ted Kremenek274b2082008-11-12 21:37:15 +000062 MIOpt.ReadToken();
Ted Kremenek274b2082008-11-12 21:37:15 +000063 return;
64 }
Ted Kremenekd6f53dc2008-11-20 07:58:05 +000065
66 // Advance to the next token.
Ted Kremenek31aba422008-11-20 16:32:22 +000067 AdvanceToken();
Ted Kremenek274b2082008-11-12 21:37:15 +000068
Ted Kremenekd6f53dc2008-11-20 07:58:05 +000069 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
Ted Kremenek274b2082008-11-12 21:37:15 +000080 MIOpt.ReadToken();
Ted Kremenekd6f53dc2008-11-20 07:58:05 +000081
82 if (Tok.is(tok::identifier)) {
83 if (LexingRawMode) return;
84 return PP->HandleIdentifier(Tok);
85 }
Ted Kremenek274b2082008-11-12 21:37:15 +000086}
87
Ted Kremenekcd4e2ae2008-11-21 00:58:35 +000088bool 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
Ted Kremenek274b2082008-11-12 21:37:15 +0000106void PTHLexer::setEOF(Token& Tok) {
Ted Kremenek31aba422008-11-20 16:32:22 +0000107 Tok = Tokens[LastTokenIdx];
Ted Kremenek274b2082008-11-12 21:37:15 +0000108}
Ted Kremenek17ff58a2008-11-19 22:21:33 +0000109
110void PTHLexer::DiscardToEndOfLine() {
111 assert(ParsingPreprocessorDirective && ParsingFilename == false &&
112 "Must be in a preprocessing directive!");
Ted Kremenek4d35da22008-11-20 01:16:50 +0000113
114 // Already at end-of-file?
Ted Kremenek31aba422008-11-20 16:32:22 +0000115 if (AtLastToken())
Ted Kremenek4d35da22008-11-20 01:16:50 +0000116 return;
117
118 // Find the first token that is not the start of the *current* line.
Ted Kremenekd2bdeed2008-11-21 23:28:56 +0000119 Token T;
120 for (Lex(T); !AtLastToken(); Lex(T))
Ted Kremenek31aba422008-11-20 16:32:22 +0000121 if (GetToken().isAtStartOfLine())
Ted Kremenek4d35da22008-11-20 01:16:50 +0000122 return;
Ted Kremenek17ff58a2008-11-19 22:21:33 +0000123}