blob: bc9e7147766a160d4bd9541d687c35acfec14ef0 [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
Ted Kremenek82a500b2008-11-27 00:38:24 +000019PTHLexer::PTHLexer(Preprocessor& pp, SourceLocation fileloc)
20 : PreprocessorLexer(&pp, fileloc), CurTokenIdx(0) {}
Ted Kremenek274b2082008-11-12 21:37:15 +000021
Ted Kremenek89d7ee92008-11-20 19:49:00 +000022Token PTHLexer::GetToken() {
23 Token Tok = Tokens[CurTokenIdx];
24
25 // If we are in raw mode, zero out identifier pointers. This is
26 // needed for 'pragma poison'. Note that this requires that the Preprocessor
27 // can go back to the original source when it calls getSpelling().
28 if (LexingRawMode && Tok.is(tok::identifier))
29 Tok.setIdentifierInfo(0);
30
31 return Tok;
32}
33
Ted Kremenek274b2082008-11-12 21:37:15 +000034void PTHLexer::Lex(Token& Tok) {
Ted Kremenekd6f53dc2008-11-20 07:58:05 +000035LexNextToken:
Ted Kremenek31aba422008-11-20 16:32:22 +000036 Tok = GetToken();
Ted Kremenek274b2082008-11-12 21:37:15 +000037
Ted Kremenekcd4e2ae2008-11-21 00:58:35 +000038 if (AtLastToken()) {
39 Preprocessor *PPCache = PP;
40
41 if (LexEndOfFile(Tok))
42 return;
43
44 assert(PPCache && "Raw buffer::LexEndOfFile should return a token");
45 return PPCache->Lex(Tok);
46 }
47
Ted Kremenekd6f53dc2008-11-20 07:58:05 +000048 // Don't advance to the next token yet. Check if we are at the
49 // start of a new line and we're processing a directive. If so, we
50 // consume this token twice, once as an tok::eom.
51 if (Tok.isAtStartOfLine() && ParsingPreprocessorDirective) {
52 ParsingPreprocessorDirective = false;
53 Tok.setKind(tok::eom);
Ted Kremenek274b2082008-11-12 21:37:15 +000054 MIOpt.ReadToken();
Ted Kremenek274b2082008-11-12 21:37:15 +000055 return;
56 }
Ted Kremenekd6f53dc2008-11-20 07:58:05 +000057
58 // Advance to the next token.
Ted Kremenek31aba422008-11-20 16:32:22 +000059 AdvanceToken();
Ted Kremenek274b2082008-11-12 21:37:15 +000060
Ted Kremenekd6f53dc2008-11-20 07:58:05 +000061 if (Tok.is(tok::hash)) {
62 if (Tok.isAtStartOfLine() && !LexingRawMode) {
63 PP->HandleDirective(Tok);
64
65 if (PP->isCurrentLexer(this))
66 goto LexNextToken;
67
68 return PP->Lex(Tok);
69 }
70 }
71
Ted Kremenek274b2082008-11-12 21:37:15 +000072 MIOpt.ReadToken();
Ted Kremenekd6f53dc2008-11-20 07:58:05 +000073
74 if (Tok.is(tok::identifier)) {
75 if (LexingRawMode) return;
76 return PP->HandleIdentifier(Tok);
77 }
Ted Kremenek274b2082008-11-12 21:37:15 +000078}
79
Ted Kremenekcd4e2ae2008-11-21 00:58:35 +000080bool PTHLexer::LexEndOfFile(Token &Tok) {
81
82 if (ParsingPreprocessorDirective) {
83 ParsingPreprocessorDirective = false;
84 Tok.setKind(tok::eom);
85 MIOpt.ReadToken();
86 return true; // Have a token.
87 }
88
89 if (LexingRawMode) {
90 MIOpt.ReadToken();
91 return true; // Have an eof token.
92 }
93
94 // FIXME: Issue diagnostics similar to Lexer.
95 return PP->HandleEndOfFile(Tok, false);
96}
97
Ted Kremenek274b2082008-11-12 21:37:15 +000098void PTHLexer::setEOF(Token& Tok) {
Ted Kremenek82a500b2008-11-27 00:38:24 +000099 assert(!Tokens.empty());
100 Tok = Tokens[Tokens.size()-1];
Ted Kremenek274b2082008-11-12 21:37:15 +0000101}
Ted Kremenek17ff58a2008-11-19 22:21:33 +0000102
103void PTHLexer::DiscardToEndOfLine() {
104 assert(ParsingPreprocessorDirective && ParsingFilename == false &&
105 "Must be in a preprocessing directive!");
Ted Kremenek4d35da22008-11-20 01:16:50 +0000106
107 // Already at end-of-file?
Ted Kremenek31aba422008-11-20 16:32:22 +0000108 if (AtLastToken())
Ted Kremenek4d35da22008-11-20 01:16:50 +0000109 return;
110
111 // Find the first token that is not the start of the *current* line.
Ted Kremenekd2bdeed2008-11-21 23:28:56 +0000112 Token T;
113 for (Lex(T); !AtLastToken(); Lex(T))
Ted Kremenek31aba422008-11-20 16:32:22 +0000114 if (GetToken().isAtStartOfLine())
Ted Kremenek4d35da22008-11-20 01:16:50 +0000115 return;
Ted Kremenek17ff58a2008-11-19 22:21:33 +0000116}