summaryrefslogtreecommitdiff
path: root/clang-r353983/include/clang/Lex/PreprocessorLexer.h
diff options
context:
space:
mode:
Diffstat (limited to 'clang-r353983/include/clang/Lex/PreprocessorLexer.h')
-rw-r--r--clang-r353983/include/clang/Lex/PreprocessorLexer.h187
1 files changed, 187 insertions, 0 deletions
diff --git a/clang-r353983/include/clang/Lex/PreprocessorLexer.h b/clang-r353983/include/clang/Lex/PreprocessorLexer.h
new file mode 100644
index 00000000..5efe5fc0
--- /dev/null
+++ b/clang-r353983/include/clang/Lex/PreprocessorLexer.h
@@ -0,0 +1,187 @@
+//===- PreprocessorLexer.h - C Language Family Lexer ------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file
+/// Defines the PreprocessorLexer interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LEX_PREPROCESSORLEXER_H
+#define LLVM_CLANG_LEX_PREPROCESSORLEXER_H
+
+#include "clang/Lex/MultipleIncludeOpt.h"
+#include "clang/Lex/Token.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
+#include <cassert>
+
+namespace clang {
+
+class FileEntry;
+class Preprocessor;
+
+class PreprocessorLexer {
+ virtual void anchor();
+
+protected:
+ friend class Preprocessor;
+
+ // Preprocessor object controlling lexing.
+ Preprocessor *PP = nullptr;
+
+ /// The SourceManager FileID corresponding to the file being lexed.
+ const FileID FID;
+
+ /// Number of SLocEntries before lexing the file.
+ unsigned InitialNumSLocEntries = 0;
+
+ //===--------------------------------------------------------------------===//
+ // Context-specific lexing flags set by the preprocessor.
+ //===--------------------------------------------------------------------===//
+
+ /// True when parsing \#XXX; turns '\\n' into a tok::eod token.
+ bool ParsingPreprocessorDirective = false;
+
+ /// True after \#include; turns \<xx> into a tok::angle_string_literal
+ /// token.
+ bool ParsingFilename = false;
+
+ /// True if in raw mode.
+ ///
+ /// Raw mode disables interpretation of tokens and is a far faster mode to
+ /// lex in than non-raw-mode. This flag:
+ /// 1. If EOF of the current lexer is found, the include stack isn't popped.
+ /// 2. Identifier information is not looked up for identifier tokens. As an
+ /// effect of this, implicit macro expansion is naturally disabled.
+ /// 3. "#" tokens at the start of a line are treated as normal tokens, not
+ /// implicitly transformed by the lexer.
+ /// 4. All diagnostic messages are disabled.
+ /// 5. No callbacks are made into the preprocessor.
+ ///
+ /// Note that in raw mode that the PP pointer may be null.
+ bool LexingRawMode = false;
+
+ /// A state machine that detects the \#ifndef-wrapping a file
+ /// idiom for the multiple-include optimization.
+ MultipleIncludeOpt MIOpt;
+
+ /// Information about the set of \#if/\#ifdef/\#ifndef blocks
+ /// we are currently in.
+ SmallVector<PPConditionalInfo, 4> ConditionalStack;
+
+ PreprocessorLexer() : FID() {}
+ PreprocessorLexer(Preprocessor *pp, FileID fid);
+ virtual ~PreprocessorLexer() = default;
+
+ virtual void IndirectLex(Token& Result) = 0;
+
+ /// Return the source location for the next observable location.
+ virtual SourceLocation getSourceLocation() = 0;
+
+ //===--------------------------------------------------------------------===//
+ // #if directive handling.
+
+ /// pushConditionalLevel - When we enter a \#if directive, this keeps track of
+ /// what we are currently in for diagnostic emission (e.g. \#if with missing
+ /// \#endif).
+ void pushConditionalLevel(SourceLocation DirectiveStart, bool WasSkipping,
+ bool FoundNonSkip, bool FoundElse) {
+ PPConditionalInfo CI;
+ CI.IfLoc = DirectiveStart;
+ CI.WasSkipping = WasSkipping;
+ CI.FoundNonSkip = FoundNonSkip;
+ CI.FoundElse = FoundElse;
+ ConditionalStack.push_back(CI);
+ }
+ void pushConditionalLevel(const PPConditionalInfo &CI) {
+ ConditionalStack.push_back(CI);
+ }
+
+ /// popConditionalLevel - Remove an entry off the top of the conditional
+ /// stack, returning information about it. If the conditional stack is empty,
+ /// this returns true and does not fill in the arguments.
+ bool popConditionalLevel(PPConditionalInfo &CI) {
+ if (ConditionalStack.empty())
+ return true;
+ CI = ConditionalStack.pop_back_val();
+ return false;
+ }
+
+ /// Return the top of the conditional stack.
+ /// \pre This requires that there be a conditional active.
+ PPConditionalInfo &peekConditionalLevel() {
+ assert(!ConditionalStack.empty() && "No conditionals active!");
+ return ConditionalStack.back();
+ }
+
+ unsigned getConditionalStackDepth() const { return ConditionalStack.size(); }
+
+public:
+ PreprocessorLexer(const PreprocessorLexer &) = delete;
+ PreprocessorLexer &operator=(const PreprocessorLexer &) = delete;
+
+ //===--------------------------------------------------------------------===//
+ // Misc. lexing methods.
+
+ /// After the preprocessor has parsed a \#include, lex and
+ /// (potentially) macro expand the filename.
+ ///
+ /// If the sequence parsed is not lexically legal, emit a diagnostic and
+ /// return a result EOD token.
+ void LexIncludeFilename(Token &FilenameTok);
+
+ /// Inform the lexer whether or not we are currently lexing a
+ /// preprocessor directive.
+ void setParsingPreprocessorDirective(bool f) {
+ ParsingPreprocessorDirective = f;
+ }
+
+ /// Return true if this lexer is in raw mode or not.
+ bool isLexingRawMode() const { return LexingRawMode; }
+
+ /// Return the preprocessor object for this lexer.
+ Preprocessor *getPP() const { return PP; }
+
+ FileID getFileID() const {
+ assert(PP &&
+ "PreprocessorLexer::getFileID() should only be used with a Preprocessor");
+ return FID;
+ }
+
+ /// Number of SLocEntries before lexing the file.
+ unsigned getInitialNumSLocEntries() const {
+ return InitialNumSLocEntries;
+ }
+
+ /// getFileEntry - Return the FileEntry corresponding to this FileID. Like
+ /// getFileID(), this only works for lexers with attached preprocessors.
+ const FileEntry *getFileEntry() const;
+
+ /// Iterator that traverses the current stack of preprocessor
+ /// conditional directives (\#if/\#ifdef/\#ifndef).
+ using conditional_iterator =
+ SmallVectorImpl<PPConditionalInfo>::const_iterator;
+
+ conditional_iterator conditional_begin() const {
+ return ConditionalStack.begin();
+ }
+
+ conditional_iterator conditional_end() const {
+ return ConditionalStack.end();
+ }
+
+ void setConditionalLevels(ArrayRef<PPConditionalInfo> CL) {
+ ConditionalStack.clear();
+ ConditionalStack.append(CL.begin(), CL.end());
+ }
+};
+
+} // namespace clang
+
+#endif // LLVM_CLANG_LEX_PREPROCESSORLEXER_H