From: Ted Kremenek Date: Wed, 12 Nov 2008 21:33:59 +0000 (+0000) Subject: Move pieces of Lexer that the Preprocessor mutates to a new base class 'PreprocessorL... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0e977de1eacfbc143bdedad87c14b53814159023;p=clang Move pieces of Lexer that the Preprocessor mutates to a new base class 'PreprocessorLexer'. This will also be the base class of the new Preprocessed-Token-Header (PTH) lexer. No functionality change. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@59168 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Lex/Lexer.h b/include/clang/Lex/Lexer.h index 33423c09f1..ed662d91ab 100644 --- a/include/clang/Lex/Lexer.h +++ b/include/clang/Lex/Lexer.h @@ -14,8 +14,7 @@ #ifndef LLVM_CLANG_LEXER_H #define LLVM_CLANG_LEXER_H -#include "clang/Lex/Token.h" -#include "clang/Lex/MultipleIncludeOpt.h" +#include "clang/Lex/PreprocessorLexer.h" #include "clang/Basic/LangOptions.h" #include "llvm/ADT/SmallVector.h" #include @@ -31,7 +30,7 @@ class Preprocessor; /// stream of tokens. This provides no support for file reading or buffering, /// or buffering/seeking of tokens, only forward lexing is supported. It relies /// on the specified Preprocessor object to handle preprocessor directives, etc. -class Lexer { +class Lexer : public PreprocessorLexer { //===--------------------------------------------------------------------===// // Constant configuration values for this lexer. const char *BufferStart; // Start of the buffer. @@ -45,27 +44,6 @@ class Lexer { // Context-specific lexing flags set by the preprocessor. // - /// ParsingPreprocessorDirective - This is true when parsing #XXX. This turns - /// '\n' into a tok::eom token. - bool ParsingPreprocessorDirective; - - /// ParsingFilename - True after #include: this turns into a - /// tok::angle_string_literal token. - bool ParsingFilename; - - /// LexingRawMode - True if in raw mode: This flag 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; - /// ExtendedTokenMode - The lexer can optionally keep comments and whitespace /// and return them as tokens. This is used for -C and -CC modes, and /// whitespace preservation can be useful for some clients that want to lex @@ -87,14 +65,6 @@ class Lexer { // IsAtStartOfLine - True if the next lexed token should get the "start of // line" flag set on it. bool IsAtStartOfLine; - - /// MIOpt - This is a state machine that detects the #ifndef-wrapping a file - /// idiom for the multiple-include optimization. - MultipleIncludeOpt MIOpt; - - /// ConditionalStack - Information about the set of #if/#ifdef/#ifndef blocks - /// we are currently in. - std::vector ConditionalStack; Lexer(const Lexer&); // DO NOT IMPLEMENT void operator=(const Lexer&); // DO NOT IMPLEMENT @@ -346,44 +316,6 @@ private: static char getCharAndSizeSlowNoWarn(const char *Ptr, unsigned &Size, const LangOptions &Features); - //===--------------------------------------------------------------------===// - // #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.back(); - ConditionalStack.pop_back(); - return false; - } - - /// peekConditionalLevel - Return the top of the conditional stack. 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(); } - //===--------------------------------------------------------------------===// // Other lexer functions. diff --git a/include/clang/Lex/PreprocessorLexer.h b/include/clang/Lex/PreprocessorLexer.h new file mode 100644 index 0000000000..7ac1eea20c --- /dev/null +++ b/include/clang/Lex/PreprocessorLexer.h @@ -0,0 +1,107 @@ +//===--- PreprocessorLexer.h - C Language Family Lexer ----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the PreprocessorLexer interface. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_PreprocessorLexer_H +#define LLVM_CLANG_PreprocessorLexer_H + +#include "clang/Lex/MultipleIncludeOpt.h" +#include "clang/Lex/Token.h" +#include + +namespace clang { + +class Preprocessor; + +class PreprocessorLexer { +protected: + // Context-specific lexing flags set by the preprocessor. + + /// ParsingPreprocessorDirective - This is true when parsing #XXX. This turns + /// '\n' into a tok::eom token. + bool ParsingPreprocessorDirective; + + /// ParsingFilename - True after #include: this turns into a + /// tok::angle_string_literal token. + bool ParsingFilename; + + /// LexingRawMode - True if in raw mode: This flag 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; + + /// MIOpt - This is a state machine that detects the #ifndef-wrapping a file + /// idiom for the multiple-include optimization. + MultipleIncludeOpt MIOpt; + + /// ConditionalStack - Information about the set of #if/#ifdef/#ifndef blocks + /// we are currently in. + std::vector ConditionalStack; + + PreprocessorLexer(const PreprocessorLexer&); // DO NOT IMPLEMENT + void operator=(const PreprocessorLexer&); // DO NOT IMPLEMENT + friend class Preprocessor; + + PreprocessorLexer() {} + +protected: + + //===--------------------------------------------------------------------===// + // #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.back(); + ConditionalStack.pop_back(); + return false; + } + + /// peekConditionalLevel - Return the top of the conditional stack. 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(); } +}; + +} // end namespace clang + +#endif