]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/llvm/tools/clang/include/clang/Lex/PreprocessorLexer.h
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / contrib / llvm / tools / clang / include / clang / Lex / PreprocessorLexer.h
1 //===--- PreprocessorLexer.h - C Language Family Lexer ----------*- C++ -*-===//
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 /// \file
11 /// \brief Defines the PreprocessorLexer interface.
12 ///
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_CLANG_PreprocessorLexer_H
16 #define LLVM_CLANG_PreprocessorLexer_H
17
18 #include "clang/Lex/MultipleIncludeOpt.h"
19 #include "clang/Lex/Token.h"
20 #include "llvm/ADT/SmallVector.h"
21
22 namespace clang {
23
24 class FileEntry;
25 class Preprocessor;
26
27 class PreprocessorLexer {
28   virtual void anchor();
29 protected:
30   Preprocessor *PP;              // Preprocessor object controlling lexing.
31
32   /// The SourceManager FileID corresponding to the file being lexed.
33   const FileID FID;
34
35   /// \brief Number of SLocEntries before lexing the file.
36   unsigned InitialNumSLocEntries;
37
38   //===--------------------------------------------------------------------===//
39   // Context-specific lexing flags set by the preprocessor.
40   //===--------------------------------------------------------------------===//
41
42   /// \brief True when parsing \#XXX; turns '\\n' into a tok::eod token.
43   bool ParsingPreprocessorDirective;
44
45   /// \brief True after \#include; turns \<xx> into a tok::angle_string_literal
46   /// token.
47   bool ParsingFilename;
48
49   /// \brief True if in raw mode.
50   ///
51   /// Raw mode disables interpretation of tokens and is a far faster mode to
52   /// lex in than non-raw-mode.  This flag:
53   ///  1. If EOF of the current lexer is found, the include stack isn't popped.
54   ///  2. Identifier information is not looked up for identifier tokens.  As an
55   ///     effect of this, implicit macro expansion is naturally disabled.
56   ///  3. "#" tokens at the start of a line are treated as normal tokens, not
57   ///     implicitly transformed by the lexer.
58   ///  4. All diagnostic messages are disabled.
59   ///  5. No callbacks are made into the preprocessor.
60   ///
61   /// Note that in raw mode that the PP pointer may be null.
62   bool LexingRawMode;
63
64   /// \brief A state machine that detects the \#ifndef-wrapping a file
65   /// idiom for the multiple-include optimization.
66   MultipleIncludeOpt MIOpt;
67
68   /// \brief Information about the set of \#if/\#ifdef/\#ifndef blocks
69   /// we are currently in.
70   SmallVector<PPConditionalInfo, 4> ConditionalStack;
71
72   PreprocessorLexer(const PreprocessorLexer &) LLVM_DELETED_FUNCTION;
73   void operator=(const PreprocessorLexer &) LLVM_DELETED_FUNCTION;
74   friend class Preprocessor;
75
76   PreprocessorLexer(Preprocessor *pp, FileID fid);
77
78   PreprocessorLexer()
79     : PP(0), InitialNumSLocEntries(0),
80       ParsingPreprocessorDirective(false),
81       ParsingFilename(false),
82       LexingRawMode(false) {}
83
84   virtual ~PreprocessorLexer() {}
85
86   virtual void IndirectLex(Token& Result) = 0;
87
88   /// \brief Return the source location for the next observable location.
89   virtual SourceLocation getSourceLocation() = 0;
90
91   //===--------------------------------------------------------------------===//
92   // #if directive handling.
93
94   /// pushConditionalLevel - When we enter a \#if directive, this keeps track of
95   /// what we are currently in for diagnostic emission (e.g. \#if with missing
96   /// \#endif).
97   void pushConditionalLevel(SourceLocation DirectiveStart, bool WasSkipping,
98                             bool FoundNonSkip, bool FoundElse) {
99     PPConditionalInfo CI;
100     CI.IfLoc = DirectiveStart;
101     CI.WasSkipping = WasSkipping;
102     CI.FoundNonSkip = FoundNonSkip;
103     CI.FoundElse = FoundElse;
104     ConditionalStack.push_back(CI);
105   }
106   void pushConditionalLevel(const PPConditionalInfo &CI) {
107     ConditionalStack.push_back(CI);
108   }
109
110   /// popConditionalLevel - Remove an entry off the top of the conditional
111   /// stack, returning information about it.  If the conditional stack is empty,
112   /// this returns true and does not fill in the arguments.
113   bool popConditionalLevel(PPConditionalInfo &CI) {
114     if (ConditionalStack.empty()) return true;
115     CI = ConditionalStack.back();
116     ConditionalStack.pop_back();
117     return false;
118   }
119
120   /// \brief Return the top of the conditional stack.
121   /// \pre This requires that there be a conditional active.
122   PPConditionalInfo &peekConditionalLevel() {
123     assert(!ConditionalStack.empty() && "No conditionals active!");
124     return ConditionalStack.back();
125   }
126
127   unsigned getConditionalStackDepth() const { return ConditionalStack.size(); }
128
129 public:
130
131   //===--------------------------------------------------------------------===//
132   // Misc. lexing methods.
133
134   /// \brief After the preprocessor has parsed a \#include, lex and
135   /// (potentially) macro expand the filename.
136   ///
137   /// If the sequence parsed is not lexically legal, emit a diagnostic and
138   /// return a result EOD token.
139   void LexIncludeFilename(Token &Result);
140
141   /// \brief Inform the lexer whether or not we are currently lexing a
142   /// preprocessor directive.
143   void setParsingPreprocessorDirective(bool f) {
144     ParsingPreprocessorDirective = f;
145   }
146
147   /// \brief Return true if this lexer is in raw mode or not.
148   bool isLexingRawMode() const { return LexingRawMode; }
149
150   /// \brief Return the preprocessor object for this lexer.
151   Preprocessor *getPP() const { return PP; }
152
153   FileID getFileID() const {
154     assert(PP &&
155       "PreprocessorLexer::getFileID() should only be used with a Preprocessor");
156     return FID;
157   }
158
159   /// \brief Number of SLocEntries before lexing the file.
160   unsigned getInitialNumSLocEntries() const {
161     return InitialNumSLocEntries;
162   }
163
164   /// getFileEntry - Return the FileEntry corresponding to this FileID.  Like
165   /// getFileID(), this only works for lexers with attached preprocessors.
166   const FileEntry *getFileEntry() const;
167
168   /// \brief Iterator that traverses the current stack of preprocessor
169   /// conditional directives (\#if/\#ifdef/\#ifndef).
170   typedef SmallVectorImpl<PPConditionalInfo>::const_iterator 
171     conditional_iterator;
172
173   conditional_iterator conditional_begin() const { 
174     return ConditionalStack.begin(); 
175   }
176   conditional_iterator conditional_end() const { 
177     return ConditionalStack.end(); 
178   }
179 };
180
181 }  // end namespace clang
182
183 #endif