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 //===--------------------------------------------------------------------===//
34 // Context-specific lexing flags set by the preprocessor.
35 //===--------------------------------------------------------------------===//
37 /// ParsingPreprocessorDirective - This is true when parsing #XXX. This turns
38 /// '\n' into a tok::eod token.
39 bool ParsingPreprocessorDirective;
41 /// ParsingFilename - True after #include: this turns <xx> into a
42 /// tok::angle_string_literal token.
45 /// LexingRawMode - True if in raw mode: This flag disables interpretation of
46 /// tokens and is a far faster mode to lex in than non-raw-mode. This flag:
47 /// 1. If EOF of the current lexer is found, the include stack isn't popped.
48 /// 2. Identifier information is not looked up for identifier tokens. As an
49 /// effect of this, implicit macro expansion is naturally disabled.
50 /// 3. "#" tokens at the start of a line are treated as normal tokens, not
51 /// implicitly transformed by the lexer.
52 /// 4. All diagnostic messages are disabled.
53 /// 5. No callbacks are made into the preprocessor.
55 /// Note that in raw mode that the PP pointer may be null.
58 /// MIOpt - This is a state machine that detects the #ifndef-wrapping a file
59 /// idiom for the multiple-include optimization.
60 MultipleIncludeOpt MIOpt;
62 /// ConditionalStack - Information about the set of #if/#ifdef/#ifndef blocks
63 /// we are currently in.
64 llvm::SmallVector<PPConditionalInfo, 4> ConditionalStack;
66 PreprocessorLexer(const PreprocessorLexer&); // DO NOT IMPLEMENT
67 void operator=(const PreprocessorLexer&); // DO NOT IMPLEMENT
68 friend class Preprocessor;
70 PreprocessorLexer(Preprocessor *pp, FileID fid)
71 : PP(pp), FID(fid), ParsingPreprocessorDirective(false),
72 ParsingFilename(false), LexingRawMode(false) {}
76 ParsingPreprocessorDirective(false),
77 ParsingFilename(false),
78 LexingRawMode(false) {}
80 virtual ~PreprocessorLexer() {}
82 virtual void IndirectLex(Token& Result) = 0;
84 /// getSourceLocation - Return the source location for the next observable
86 virtual SourceLocation getSourceLocation() = 0;
88 //===--------------------------------------------------------------------===//
89 // #if directive handling.
91 /// pushConditionalLevel - When we enter a #if directive, this keeps track of
92 /// what we are currently in for diagnostic emission (e.g. #if with missing
94 void pushConditionalLevel(SourceLocation DirectiveStart, bool WasSkipping,
95 bool FoundNonSkip, bool FoundElse) {
97 CI.IfLoc = DirectiveStart;
98 CI.WasSkipping = WasSkipping;
99 CI.FoundNonSkip = FoundNonSkip;
100 CI.FoundElse = FoundElse;
101 ConditionalStack.push_back(CI);
103 void pushConditionalLevel(const PPConditionalInfo &CI) {
104 ConditionalStack.push_back(CI);
107 /// popConditionalLevel - Remove an entry off the top of the conditional
108 /// stack, returning information about it. If the conditional stack is empty,
109 /// this returns true and does not fill in the arguments.
110 bool popConditionalLevel(PPConditionalInfo &CI) {
111 if (ConditionalStack.empty()) return true;
112 CI = ConditionalStack.back();
113 ConditionalStack.pop_back();
117 /// peekConditionalLevel - Return the top of the conditional stack. This
118 /// requires that there be a conditional active.
119 PPConditionalInfo &peekConditionalLevel() {
120 assert(!ConditionalStack.empty() && "No conditionals active!");
121 return ConditionalStack.back();
124 unsigned getConditionalStackDepth() const { return ConditionalStack.size(); }
128 //===--------------------------------------------------------------------===//
129 // Misc. lexing methods.
131 /// LexIncludeFilename - After the preprocessor has parsed a #include, lex and
132 /// (potentially) macro expand the filename. If the sequence parsed is not
133 /// lexically legal, emit a diagnostic and return a result EOD token.
134 void LexIncludeFilename(Token &Result);
136 /// setParsingPreprocessorDirective - Inform the lexer whether or not
137 /// we are currently lexing a preprocessor directive.
138 void setParsingPreprocessorDirective(bool f) {
139 ParsingPreprocessorDirective = f;
142 /// isLexingRawMode - Return true if this lexer is in raw mode or not.
143 bool isLexingRawMode() const { return LexingRawMode; }
145 /// getPP - Return the preprocessor object for this lexer.
146 Preprocessor *getPP() const { return PP; }
148 FileID getFileID() const {
150 "PreprocessorLexer::getFileID() should only be used with a Preprocessor");
154 /// getFileEntry - Return the FileEntry corresponding to this FileID. Like
155 /// getFileID(), this only works for lexers with attached preprocessors.
156 const FileEntry *getFileEntry() const;
158 /// \brief Iterator that traverses the current stack of preprocessor
159 /// conditional directives (#if/#ifdef/#ifndef).
160 typedef llvm::SmallVectorImpl<PPConditionalInfo>::const_iterator
161 conditional_iterator;
163 conditional_iterator conditional_begin() const {
164 return ConditionalStack.begin();
166 conditional_iterator conditional_end() const {
167 return ConditionalStack.end();
171 } // end namespace clang