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