clang 17.0.0git
PreprocessorLexer.h
Go to the documentation of this file.
1//===- PreprocessorLexer.h - C Language Family Lexer ------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9/// \file
10/// Defines the PreprocessorLexer interface.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_LEX_PREPROCESSORLEXER_H
15#define LLVM_CLANG_LEX_PREPROCESSORLEXER_H
16
20#include "clang/Lex/Token.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
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.
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.
51
52 /// True after \#include; turns <xx> or "xxx" into a tok::header_name token.
53 bool ParsingFilename = false;
54
55 /// True if in raw mode.
56 ///
57 /// Raw mode disables interpretation of tokens and is a far faster mode to
58 /// lex in than non-raw-mode. This flag:
59 /// 1. If EOF of the current lexer is found, the include stack isn't popped.
60 /// 2. Identifier information is not looked up for identifier tokens. As an
61 /// effect of this, implicit macro expansion is naturally disabled.
62 /// 3. "#" tokens at the start of a line are treated as normal tokens, not
63 /// implicitly transformed by the lexer.
64 /// 4. All diagnostic messages are disabled.
65 /// 5. No callbacks are made into the preprocessor.
66 ///
67 /// Note that in raw mode that the PP pointer may be null.
68 bool LexingRawMode = false;
69
70 /// A state machine that detects the \#ifndef-wrapping a file
71 /// idiom for the multiple-include optimization.
73
74 /// Information about the set of \#if/\#ifdef/\#ifndef blocks
75 /// we are currently in.
77
80 virtual ~PreprocessorLexer() = default;
81
82 virtual void IndirectLex(Token& Result) = 0;
83
84 /// Return the source location for the next observable location.
86
87 //===--------------------------------------------------------------------===//
88 // #if directive handling.
89
90 /// pushConditionalLevel - When we enter a \#if directive, this keeps track of
91 /// what we are currently in for diagnostic emission (e.g. \#if with missing
92 /// \#endif).
93 void pushConditionalLevel(SourceLocation DirectiveStart, bool WasSkipping,
94 bool FoundNonSkip, bool FoundElse) {
96 CI.IfLoc = DirectiveStart;
97 CI.WasSkipping = WasSkipping;
98 CI.FoundNonSkip = FoundNonSkip;
99 CI.FoundElse = FoundElse;
100 ConditionalStack.push_back(CI);
101 }
103 ConditionalStack.push_back(CI);
104 }
105
106 /// popConditionalLevel - Remove an entry off the top of the conditional
107 /// stack, returning information about it. If the conditional stack is empty,
108 /// this returns true and does not fill in the arguments.
110 if (ConditionalStack.empty())
111 return true;
112 CI = ConditionalStack.pop_back_val();
113 return false;
114 }
115
116 /// Return the top of the conditional stack.
117 /// \pre This requires that there be a conditional active.
119 assert(!ConditionalStack.empty() && "No conditionals active!");
120 return ConditionalStack.back();
121 }
122
123 unsigned getConditionalStackDepth() const { return ConditionalStack.size(); }
124
125public:
128
129 //===--------------------------------------------------------------------===//
130 // Misc. lexing methods.
131
132 /// Lex a token, producing a header-name token if possible.
133 void LexIncludeFilename(Token &FilenameTok);
134
135 /// Inform the lexer whether or not we are currently lexing a
136 /// preprocessor directive.
139 }
140
141 /// Return true if this lexer is in raw mode or not.
142 bool isLexingRawMode() const { return LexingRawMode; }
143
144 /// Return the preprocessor object for this lexer.
145 Preprocessor *getPP() const { return PP; }
146
148 assert(PP &&
149 "PreprocessorLexer::getFileID() should only be used with a Preprocessor");
150 return FID;
151 }
152
153 /// Number of SLocEntries before lexing the file.
154 unsigned getInitialNumSLocEntries() const {
156 }
157
158 /// getFileEntry - Return the FileEntry corresponding to this FileID. Like
159 /// getFileID(), this only works for lexers with attached preprocessors.
161
162 /// Iterator that traverses the current stack of preprocessor
163 /// conditional directives (\#if/\#ifdef/\#ifndef).
166
168 return ConditionalStack.begin();
169 }
170
172 return ConditionalStack.end();
173 }
174
176 ConditionalStack.clear();
177 ConditionalStack.append(CL.begin(), CL.end());
178 }
179};
180
181} // namespace clang
182
183#endif // LLVM_CLANG_LEX_PREPROCESSORLEXER_H
Defines interfaces for clang::FileEntry and clang::FileEntryRef.
Defines the MultipleIncludeOpt interface.
Defines the clang::SourceLocation class and associated facilities.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Implements the simple state machine that the Lexer class uses to detect files subject to the 'multipl...
Wrapper around OptionalFileEntryRef that degrades to 'const FileEntry*', facilitating incremental pat...
Definition: FileEntry.h:293
OptionalFileEntryRefDegradesToFileEntryPtr getFileEntry() const
getFileEntry - Return the FileEntry corresponding to this FileID.
conditional_iterator conditional_begin() const
unsigned getInitialNumSLocEntries() const
Number of SLocEntries before lexing the file.
virtual void IndirectLex(Token &Result)=0
conditional_iterator conditional_end() const
SmallVectorImpl< PPConditionalInfo >::const_iterator conditional_iterator
Iterator that traverses the current stack of preprocessor conditional directives (#if/#ifdef/#ifndef)...
void pushConditionalLevel(SourceLocation DirectiveStart, bool WasSkipping, bool FoundNonSkip, bool FoundElse)
pushConditionalLevel - When we enter a #if directive, this keeps track of what we are currently in fo...
PreprocessorLexer & operator=(const PreprocessorLexer &)=delete
unsigned getConditionalStackDepth() const
bool LexingRawMode
True if in raw mode.
PreprocessorLexer(const PreprocessorLexer &)=delete
virtual ~PreprocessorLexer()=default
void setParsingPreprocessorDirective(bool f)
Inform the lexer whether or not we are currently lexing a preprocessor directive.
SmallVector< PPConditionalInfo, 4 > ConditionalStack
Information about the set of #if/#ifdef/#ifndef blocks we are currently in.
bool ParsingPreprocessorDirective
True when parsing #XXX; turns '\n' into a tok::eod token.
void pushConditionalLevel(const PPConditionalInfo &CI)
MultipleIncludeOpt MIOpt
A state machine that detects the #ifndef-wrapping a file idiom for the multiple-include optimization.
void setConditionalLevels(ArrayRef< PPConditionalInfo > CL)
bool popConditionalLevel(PPConditionalInfo &CI)
popConditionalLevel - Remove an entry off the top of the conditional stack, returning information abo...
bool ParsingFilename
True after #include; turns <xx> or "xxx" into a tok::header_name token.
void LexIncludeFilename(Token &FilenameTok)
Lex a token, producing a header-name token if possible.
PPConditionalInfo & peekConditionalLevel()
Return the top of the conditional stack.
bool isLexingRawMode() const
Return true if this lexer is in raw mode or not.
unsigned InitialNumSLocEntries
Number of SLocEntries before lexing the file.
Preprocessor * getPP() const
Return the preprocessor object for this lexer.
virtual SourceLocation getSourceLocation()=0
Return the source location for the next observable location.
const FileID FID
The SourceManager FileID corresponding to the file being lexed.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
Definition: Preprocessor.h:128
Encodes a location in the source.
Token - This structure provides full information about a lexed token.
Definition: Token.h:35
@ Result
The result type of a method or function.
Information about the conditional stack (#if directives) currently active.
Definition: Token.h:317
bool FoundNonSkip
True if we have emitted tokens already, and now we're in an #else block or something.
Definition: Token.h:327
SourceLocation IfLoc
Location where the conditional started.
Definition: Token.h:319
bool WasSkipping
True if this was contained in a skipping directive, e.g., in a "\#if 0" block.
Definition: Token.h:323
bool FoundElse
True if we've seen a #else in this block.
Definition: Token.h:331