Warning: That file was not part of the compilation database. It may have many parsing errors.

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/// 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
25namespace clang {
26
27class FileEntry;
28class Preprocessor;
29
30class PreprocessorLexer {
31 virtual void anchor();
32
33protected:
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 /// 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 /// True when parsing \#XXX; turns '\\n' into a tok::eod token.
50 bool ParsingPreprocessorDirective = false;
51
52 /// True after \#include; turns \<xx> into a tok::angle_string_literal
53 /// token.
54 bool ParsingFilename = false;
55
56 /// 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 /// A state machine that detects the \#ifndef-wrapping a file
72 /// idiom for the multiple-include optimization.
73 MultipleIncludeOpt MIOpt;
74
75 /// 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 /// 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 /// 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
126public:
127 PreprocessorLexer(const PreprocessorLexer &) = delete;
128 PreprocessorLexer &operator=(const PreprocessorLexer &) = delete;
129
130 //===--------------------------------------------------------------------===//
131 // Misc. lexing methods.
132
133 /// 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 /// 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 /// Return true if this lexer is in raw mode or not.
147 bool isLexingRawMode() const { return LexingRawMode; }
148
149 /// 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 /// 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 /// 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
189

Warning: That file was not part of the compilation database. It may have many parsing errors.