diff options
| author | Ralf Luther <luther.ralf@gmail.com> | 2019-03-27 20:23:17 +0000 |
|---|---|---|
| committer | Gerrit Code Review <gerrit2@aicp-server-3> | 2019-03-27 20:23:17 +0000 |
| commit | 1ce3a9d272e564b22a1333a1e36a3d3ab7cfab01 (patch) | |
| tree | 391382eadd4fec5bb480f2e8934fa352770221d1 /clang-r353983/include/clang/Lex/PreprocessorLexer.h | |
| parent | d1d48b140bafaa8a50107292f5fce95562575765 (diff) | |
| parent | 4f56932d3416ac03f646bc1a611b3135fec2fe08 (diff) | |
Merge "Update prebuilt Clang to r353983." into p9.0HEADp9.0-backupp9.0
Diffstat (limited to 'clang-r353983/include/clang/Lex/PreprocessorLexer.h')
| -rw-r--r-- | clang-r353983/include/clang/Lex/PreprocessorLexer.h | 187 |
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 |
