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"
27 class PreprocessorLexer {
29 Preprocessor *PP; // Preprocessor object controlling lexing.
31 /// The SourceManager FileID corresponding to the file being lexed.
34 //===--------------------------------------------------------------------===//
35 // Context-specific lexing flags set by the preprocessor.
36 //===--------------------------------------------------------------------===//
38 /// ParsingPreprocessorDirective - This is true when parsing #XXX. This turns
39 /// '\n' into a tok::eom token.
40 bool ParsingPreprocessorDirective;
42 /// ParsingFilename - True after #include: this turns <xx> into a
43 /// tok::angle_string_literal token.
46 /// LexingRawMode - True if in raw mode: This flag disables interpretation of
47 /// tokens and is a far faster mode to lex in than non-raw-mode. This flag:
48 /// 1. If EOF of the current lexer is found, the include stack isn't popped.
49 /// 2. Identifier information is not looked up for identifier tokens. As an
50 /// effect of this, implicit macro expansion is naturally disabled.
51 /// 3. "#" tokens at the start of a line are treated as normal tokens, not
52 /// implicitly transformed by the lexer.
53 /// 4. All diagnostic messages are disabled.
54 /// 5. No callbacks are made into the preprocessor.
56 /// Note that in raw mode that the PP pointer may be null.
59 /// MIOpt - This is a state machine that detects the #ifndef-wrapping a file
60 /// idiom for the multiple-include optimization.
61 MultipleIncludeOpt MIOpt;
63 /// ConditionalStack - Information about the set of #if/#ifdef/#ifndef blocks
64 /// we are currently in.
65 llvm::SmallVector<PPConditionalInfo, 4> ConditionalStack;
67 PreprocessorLexer(const PreprocessorLexer&); // DO NOT IMPLEMENT
68 void operator=(const PreprocessorLexer&); // DO NOT IMPLEMENT
69 friend class Preprocessor;
71 PreprocessorLexer(Preprocessor *pp, FileID fid)
72 : PP(pp), FID(fid), ParsingPreprocessorDirective(false),
73 ParsingFilename(false), LexingRawMode(false) {}
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 EOM 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 /// getFileEntry - Return the FileEntry corresponding to this FileID. Like
156 /// getFileID(), this only works for lexers with attached preprocessors.
157 const FileEntry *getFileEntry() const;
159 /// \brief Iterator that traverses the current stack of preprocessor
160 /// conditional directives (#if/#ifdef/#ifndef).
161 typedef llvm::SmallVectorImpl<PPConditionalInfo>::const_iterator
162 conditional_iterator;
164 conditional_iterator conditional_begin() const {
165 return ConditionalStack.begin();
167 conditional_iterator conditional_end() const {
168 return ConditionalStack.end();
172 } // end namespace clang