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