1 //===--- PreprocessorLexer.h - C Language Family Lexer ----------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the PreprocessorLexer interface.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_PreprocessorLexer_H
15 #define LLVM_CLANG_PreprocessorLexer_H
17 #include "clang/Lex/MultipleIncludeOpt.h"
18 #include "clang/Lex/Token.h"
19 #include "llvm/ADT/SmallVector.h"
26 class PreprocessorLexer {
28 Preprocessor *PP; // Preprocessor object controlling lexing.
30 /// The SourceManager FileID corresponding to the file being lexed.
33 /// \brief Number of SLocEntries before lexing the file.
34 unsigned InitialNumSLocEntries;
36 //===--------------------------------------------------------------------===//
37 // Context-specific lexing flags set by the preprocessor.
38 //===--------------------------------------------------------------------===//
40 /// ParsingPreprocessorDirective - This is true when parsing #XXX. This turns
41 /// '\n' into a tok::eod token.
42 bool ParsingPreprocessorDirective;
44 /// ParsingFilename - True after #include: this turns <xx> into a
45 /// tok::angle_string_literal token.
48 /// LexingRawMode - True if in raw mode: This flag disables interpretation of
49 /// tokens and is a far faster mode to lex in than non-raw-mode. This flag:
50 /// 1. If EOF of the current lexer is found, the include stack isn't popped.
51 /// 2. Identifier information is not looked up for identifier tokens. As an
52 /// effect of this, implicit macro expansion is naturally disabled.
53 /// 3. "#" tokens at the start of a line are treated as normal tokens, not
54 /// implicitly transformed by the lexer.
55 /// 4. All diagnostic messages are disabled.
56 /// 5. No callbacks are made into the preprocessor.
58 /// Note that in raw mode that the PP pointer may be null.
61 /// MIOpt - This is a state machine that detects the #ifndef-wrapping a file
62 /// idiom for the multiple-include optimization.
63 MultipleIncludeOpt MIOpt;
65 /// ConditionalStack - Information about the set of #if/#ifdef/#ifndef blocks
66 /// we are currently in.
67 SmallVector<PPConditionalInfo, 4> ConditionalStack;
69 PreprocessorLexer(const PreprocessorLexer&); // DO NOT IMPLEMENT
70 void operator=(const PreprocessorLexer&); // DO NOT IMPLEMENT
71 friend class Preprocessor;
73 PreprocessorLexer(Preprocessor *pp, FileID fid);
76 : PP(0), InitialNumSLocEntries(0),
77 ParsingPreprocessorDirective(false),
78 ParsingFilename(false),
79 LexingRawMode(false) {}
81 virtual ~PreprocessorLexer() {}
83 virtual void IndirectLex(Token& Result) = 0;
85 /// getSourceLocation - Return the source location for the next observable
87 virtual SourceLocation getSourceLocation() = 0;
89 //===--------------------------------------------------------------------===//
90 // #if directive handling.
92 /// pushConditionalLevel - When we enter a #if directive, this keeps track of
93 /// what we are currently in for diagnostic emission (e.g. #if with missing
95 void pushConditionalLevel(SourceLocation DirectiveStart, bool WasSkipping,
96 bool FoundNonSkip, bool FoundElse) {
98 CI.IfLoc = DirectiveStart;
99 CI.WasSkipping = WasSkipping;
100 CI.FoundNonSkip = FoundNonSkip;
101 CI.FoundElse = FoundElse;
102 ConditionalStack.push_back(CI);
104 void pushConditionalLevel(const PPConditionalInfo &CI) {
105 ConditionalStack.push_back(CI);
108 /// popConditionalLevel - Remove an entry off the top of the conditional
109 /// stack, returning information about it. If the conditional stack is empty,
110 /// this returns true and does not fill in the arguments.
111 bool popConditionalLevel(PPConditionalInfo &CI) {
112 if (ConditionalStack.empty()) return true;
113 CI = ConditionalStack.back();
114 ConditionalStack.pop_back();
118 /// peekConditionalLevel - Return the top of the conditional stack. This
119 /// requires that there be a conditional active.
120 PPConditionalInfo &peekConditionalLevel() {
121 assert(!ConditionalStack.empty() && "No conditionals active!");
122 return ConditionalStack.back();
125 unsigned getConditionalStackDepth() const { return ConditionalStack.size(); }
129 //===--------------------------------------------------------------------===//
130 // Misc. lexing methods.
132 /// LexIncludeFilename - After the preprocessor has parsed a #include, lex and
133 /// (potentially) macro expand the filename. If the sequence parsed is not
134 /// lexically legal, emit a diagnostic and return a result EOD token.
135 void LexIncludeFilename(Token &Result);
137 /// setParsingPreprocessorDirective - Inform the lexer whether or not
138 /// we are currently lexing a preprocessor directive.
139 void setParsingPreprocessorDirective(bool f) {
140 ParsingPreprocessorDirective = f;
143 /// isLexingRawMode - Return true if this lexer is in raw mode or not.
144 bool isLexingRawMode() const { return LexingRawMode; }
146 /// getPP - Return the preprocessor object for this lexer.
147 Preprocessor *getPP() const { return PP; }
149 FileID getFileID() const {
151 "PreprocessorLexer::getFileID() should only be used with a Preprocessor");
155 /// \brief Number of SLocEntries before lexing the file.
156 unsigned getInitialNumSLocEntries() const {
157 return InitialNumSLocEntries;
160 /// getFileEntry - Return the FileEntry corresponding to this FileID. Like
161 /// getFileID(), this only works for lexers with attached preprocessors.
162 const FileEntry *getFileEntry() const;
164 /// \brief Iterator that traverses the current stack of preprocessor
165 /// conditional directives (#if/#ifdef/#ifndef).
166 typedef SmallVectorImpl<PPConditionalInfo>::const_iterator
167 conditional_iterator;
169 conditional_iterator conditional_begin() const {
170 return ConditionalStack.begin();
172 conditional_iterator conditional_end() const {
173 return ConditionalStack.end();
177 } // end namespace clang