Ted Kremenek | 0e977de | 2008-11-12 21:33:59 +0000 | [diff] [blame] | 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 | //===----------------------------------------------------------------------===// |
James Dennett | 80b5a2f | 2012-06-20 00:48:54 +0000 | [diff] [blame] | 9 | /// |
| 10 | /// \file |
| 11 | /// \brief Defines the PreprocessorLexer interface. |
| 12 | /// |
Ted Kremenek | 0e977de | 2008-11-12 21:33:59 +0000 | [diff] [blame] | 13 | //===----------------------------------------------------------------------===// |
| 14 | |
| 15 | #ifndef LLVM_CLANG_PreprocessorLexer_H |
| 16 | #define LLVM_CLANG_PreprocessorLexer_H |
| 17 | |
| 18 | #include "clang/Lex/MultipleIncludeOpt.h" |
| 19 | #include "clang/Lex/Token.h" |
Chris Lattner | 3a874a4 | 2009-01-18 02:52:26 +0000 | [diff] [blame] | 20 | #include "llvm/ADT/SmallVector.h" |
Mike Stump | 79d39f9 | 2009-09-09 13:12:01 +0000 | [diff] [blame] | 21 | |
Ted Kremenek | 0e977de | 2008-11-12 21:33:59 +0000 | [diff] [blame] | 22 | namespace clang { |
| 23 | |
Daniel Dunbar | 0cc70f1 | 2010-03-30 17:57:47 +0000 | [diff] [blame] | 24 | class FileEntry; |
Ted Kremenek | 0e977de | 2008-11-12 21:33:59 +0000 | [diff] [blame] | 25 | class Preprocessor; |
| 26 | |
| 27 | class PreprocessorLexer { |
David Blaikie | 99ba9e3 | 2011-12-20 02:48:34 +0000 | [diff] [blame] | 28 | virtual void anchor(); |
Ted Kremenek | d6a2e7d | 2008-11-12 23:13:54 +0000 | [diff] [blame] | 29 | protected: |
| 30 | Preprocessor *PP; // Preprocessor object controlling lexing. |
Ted Kremenek | 41938c8 | 2008-11-19 21:57:25 +0000 | [diff] [blame] | 31 | |
Chris Lattner | 2b2453a | 2009-01-17 06:22:33 +0000 | [diff] [blame] | 32 | /// The SourceManager FileID corresponding to the file being lexed. |
| 33 | const FileID FID; |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 34 | |
Argyrios Kyrtzidis | d9d2b67 | 2011-08-21 23:33:04 +0000 | [diff] [blame] | 35 | /// \brief Number of SLocEntries before lexing the file. |
| 36 | unsigned InitialNumSLocEntries; |
| 37 | |
Ted Kremenek | d6a2e7d | 2008-11-12 23:13:54 +0000 | [diff] [blame] | 38 | //===--------------------------------------------------------------------===// |
Ted Kremenek | 0e977de | 2008-11-12 21:33:59 +0000 | [diff] [blame] | 39 | // Context-specific lexing flags set by the preprocessor. |
Ted Kremenek | d6a2e7d | 2008-11-12 23:13:54 +0000 | [diff] [blame] | 40 | //===--------------------------------------------------------------------===// |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 41 | |
James Dennett | 80b5a2f | 2012-06-20 00:48:54 +0000 | [diff] [blame] | 42 | /// \brief True when parsing \#XXX; turns '\\n' into a tok::eod token. |
Ted Kremenek | 0e977de | 2008-11-12 21:33:59 +0000 | [diff] [blame] | 43 | bool ParsingPreprocessorDirective; |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 44 | |
James Dennett | 80b5a2f | 2012-06-20 00:48:54 +0000 | [diff] [blame] | 45 | /// \brief True after \#include; turns \<xx> into a tok::angle_string_literal |
| 46 | /// token. |
Ted Kremenek | 0e977de | 2008-11-12 21:33:59 +0000 | [diff] [blame] | 47 | bool ParsingFilename; |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 48 | |
James Dennett | 80b5a2f | 2012-06-20 00:48:54 +0000 | [diff] [blame] | 49 | /// \brief True if in raw mode. |
| 50 | /// |
| 51 | /// Raw mode disables interpretation of tokens and is a far faster mode to |
| 52 | /// lex in than non-raw-mode. This flag: |
Ted Kremenek | 0e977de | 2008-11-12 21:33:59 +0000 | [diff] [blame] | 53 | /// 1. If EOF of the current lexer is found, the include stack isn't popped. |
| 54 | /// 2. Identifier information is not looked up for identifier tokens. As an |
| 55 | /// effect of this, implicit macro expansion is naturally disabled. |
| 56 | /// 3. "#" tokens at the start of a line are treated as normal tokens, not |
| 57 | /// implicitly transformed by the lexer. |
| 58 | /// 4. All diagnostic messages are disabled. |
| 59 | /// 5. No callbacks are made into the preprocessor. |
| 60 | /// |
| 61 | /// Note that in raw mode that the PP pointer may be null. |
| 62 | bool LexingRawMode; |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 63 | |
James Dennett | 80b5a2f | 2012-06-20 00:48:54 +0000 | [diff] [blame] | 64 | /// \brief A state machine that detects the \#ifndef-wrapping a file |
Ted Kremenek | 0e977de | 2008-11-12 21:33:59 +0000 | [diff] [blame] | 65 | /// idiom for the multiple-include optimization. |
| 66 | MultipleIncludeOpt MIOpt; |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 67 | |
James Dennett | 80b5a2f | 2012-06-20 00:48:54 +0000 | [diff] [blame] | 68 | /// \brief Information about the set of \#if/\#ifdef/\#ifndef blocks |
Ted Kremenek | 0e977de | 2008-11-12 21:33:59 +0000 | [diff] [blame] | 69 | /// we are currently in. |
Chris Lattner | 686775d | 2011-07-20 06:58:45 +0000 | [diff] [blame] | 70 | SmallVector<PPConditionalInfo, 4> ConditionalStack; |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 71 | |
Dmitri Gribenko | f56faa0 | 2012-09-15 20:20:27 +0000 | [diff] [blame] | 72 | PreprocessorLexer(const PreprocessorLexer &) LLVM_DELETED_FUNCTION; |
| 73 | void operator=(const PreprocessorLexer &) LLVM_DELETED_FUNCTION; |
Ted Kremenek | 0e977de | 2008-11-12 21:33:59 +0000 | [diff] [blame] | 74 | friend class Preprocessor; |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 75 | |
Argyrios Kyrtzidis | d9d2b67 | 2011-08-21 23:33:04 +0000 | [diff] [blame] | 76 | PreprocessorLexer(Preprocessor *pp, FileID fid); |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 77 | |
Ted Kremenek | 452e378 | 2008-11-20 01:29:45 +0000 | [diff] [blame] | 78 | PreprocessorLexer() |
Argyrios Kyrtzidis | d9d2b67 | 2011-08-21 23:33:04 +0000 | [diff] [blame] | 79 | : PP(0), InitialNumSLocEntries(0), |
Ted Kremenek | 452e378 | 2008-11-20 01:29:45 +0000 | [diff] [blame] | 80 | ParsingPreprocessorDirective(false), |
| 81 | ParsingFilename(false), |
Daniel Dunbar | 6e64973 | 2012-11-13 19:12:37 +0000 | [diff] [blame^] | 82 | LexingRawMode(false) {} |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 83 | |
Chris Lattner | 2b2453a | 2009-01-17 06:22:33 +0000 | [diff] [blame] | 84 | virtual ~PreprocessorLexer() {} |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 85 | |
Ted Kremenek | eb41c28 | 2008-11-12 22:46:33 +0000 | [diff] [blame] | 86 | virtual void IndirectLex(Token& Result) = 0; |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 87 | |
James Dennett | 80b5a2f | 2012-06-20 00:48:54 +0000 | [diff] [blame] | 88 | /// \brief Return the source location for the next observable location. |
Ted Kremenek | bc0f6bc | 2008-12-10 23:20:59 +0000 | [diff] [blame] | 89 | virtual SourceLocation getSourceLocation() = 0; |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 90 | |
Ted Kremenek | 0e977de | 2008-11-12 21:33:59 +0000 | [diff] [blame] | 91 | //===--------------------------------------------------------------------===// |
| 92 | // #if directive handling. |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 93 | |
James Dennett | 80b5a2f | 2012-06-20 00:48:54 +0000 | [diff] [blame] | 94 | /// pushConditionalLevel - When we enter a \#if directive, this keeps track of |
| 95 | /// what we are currently in for diagnostic emission (e.g. \#if with missing |
| 96 | /// \#endif). |
Ted Kremenek | 0e977de | 2008-11-12 21:33:59 +0000 | [diff] [blame] | 97 | void pushConditionalLevel(SourceLocation DirectiveStart, bool WasSkipping, |
| 98 | bool FoundNonSkip, bool FoundElse) { |
| 99 | PPConditionalInfo CI; |
| 100 | CI.IfLoc = DirectiveStart; |
| 101 | CI.WasSkipping = WasSkipping; |
| 102 | CI.FoundNonSkip = FoundNonSkip; |
| 103 | CI.FoundElse = FoundElse; |
| 104 | ConditionalStack.push_back(CI); |
| 105 | } |
| 106 | void pushConditionalLevel(const PPConditionalInfo &CI) { |
| 107 | ConditionalStack.push_back(CI); |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 108 | } |
| 109 | |
Ted Kremenek | 0e977de | 2008-11-12 21:33:59 +0000 | [diff] [blame] | 110 | /// popConditionalLevel - Remove an entry off the top of the conditional |
| 111 | /// stack, returning information about it. If the conditional stack is empty, |
| 112 | /// this returns true and does not fill in the arguments. |
| 113 | bool popConditionalLevel(PPConditionalInfo &CI) { |
| 114 | if (ConditionalStack.empty()) return true; |
| 115 | CI = ConditionalStack.back(); |
| 116 | ConditionalStack.pop_back(); |
| 117 | return false; |
| 118 | } |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 119 | |
James Dennett | 80b5a2f | 2012-06-20 00:48:54 +0000 | [diff] [blame] | 120 | /// \brief Return the top of the conditional stack. |
| 121 | /// \pre This requires that there be a conditional active. |
Ted Kremenek | 0e977de | 2008-11-12 21:33:59 +0000 | [diff] [blame] | 122 | PPConditionalInfo &peekConditionalLevel() { |
| 123 | assert(!ConditionalStack.empty() && "No conditionals active!"); |
| 124 | return ConditionalStack.back(); |
| 125 | } |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 126 | |
| 127 | unsigned getConditionalStackDepth() const { return ConditionalStack.size(); } |
Ted Kremenek | 63db2a7 | 2008-11-26 00:57:02 +0000 | [diff] [blame] | 128 | |
| 129 | public: |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 130 | |
Ted Kremenek | eb41c28 | 2008-11-12 22:46:33 +0000 | [diff] [blame] | 131 | //===--------------------------------------------------------------------===// |
| 132 | // Misc. lexing methods. |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 133 | |
James Dennett | 80b5a2f | 2012-06-20 00:48:54 +0000 | [diff] [blame] | 134 | /// \brief After the preprocessor has parsed a \#include, lex and |
| 135 | /// (potentially) macro expand the filename. |
| 136 | /// |
| 137 | /// If the sequence parsed is not lexically legal, emit a diagnostic and |
| 138 | /// return a result EOD token. |
Ted Kremenek | eb41c28 | 2008-11-12 22:46:33 +0000 | [diff] [blame] | 139 | void LexIncludeFilename(Token &Result); |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 140 | |
James Dennett | 80b5a2f | 2012-06-20 00:48:54 +0000 | [diff] [blame] | 141 | /// \brief Inform the lexer whether or not we are currently lexing a |
| 142 | /// preprocessor directive. |
Ted Kremenek | 63db2a7 | 2008-11-26 00:57:02 +0000 | [diff] [blame] | 143 | void setParsingPreprocessorDirective(bool f) { |
| 144 | ParsingPreprocessorDirective = f; |
| 145 | } |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 146 | |
James Dennett | 80b5a2f | 2012-06-20 00:48:54 +0000 | [diff] [blame] | 147 | /// \brief Return true if this lexer is in raw mode or not. |
Chris Lattner | 74d15df | 2008-11-22 02:02:22 +0000 | [diff] [blame] | 148 | bool isLexingRawMode() const { return LexingRawMode; } |
| 149 | |
James Dennett | 80b5a2f | 2012-06-20 00:48:54 +0000 | [diff] [blame] | 150 | /// \brief Return the preprocessor object for this lexer. |
Chris Lattner | 74d15df | 2008-11-22 02:02:22 +0000 | [diff] [blame] | 151 | Preprocessor *getPP() const { return PP; } |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 152 | |
| 153 | FileID getFileID() const { |
Ted Kremenek | 41938c8 | 2008-11-19 21:57:25 +0000 | [diff] [blame] | 154 | assert(PP && |
| 155 | "PreprocessorLexer::getFileID() should only be used with a Preprocessor"); |
Chris Lattner | 2b2453a | 2009-01-17 06:22:33 +0000 | [diff] [blame] | 156 | return FID; |
Ted Kremenek | 41938c8 | 2008-11-19 21:57:25 +0000 | [diff] [blame] | 157 | } |
Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 158 | |
Argyrios Kyrtzidis | d9d2b67 | 2011-08-21 23:33:04 +0000 | [diff] [blame] | 159 | /// \brief Number of SLocEntries before lexing the file. |
| 160 | unsigned getInitialNumSLocEntries() const { |
| 161 | return InitialNumSLocEntries; |
| 162 | } |
| 163 | |
Chris Lattner | 2b2453a | 2009-01-17 06:22:33 +0000 | [diff] [blame] | 164 | /// getFileEntry - Return the FileEntry corresponding to this FileID. Like |
| 165 | /// getFileID(), this only works for lexers with attached preprocessors. |
| 166 | const FileEntry *getFileEntry() const; |
Douglas Gregor | 6f2d1b1 | 2010-10-18 14:43:21 +0000 | [diff] [blame] | 167 | |
| 168 | /// \brief Iterator that traverses the current stack of preprocessor |
James Dennett | 809d1be | 2012-06-13 22:07:09 +0000 | [diff] [blame] | 169 | /// conditional directives (\#if/\#ifdef/\#ifndef). |
Chris Lattner | 686775d | 2011-07-20 06:58:45 +0000 | [diff] [blame] | 170 | typedef SmallVectorImpl<PPConditionalInfo>::const_iterator |
Douglas Gregor | 6f2d1b1 | 2010-10-18 14:43:21 +0000 | [diff] [blame] | 171 | conditional_iterator; |
| 172 | |
| 173 | conditional_iterator conditional_begin() const { |
| 174 | return ConditionalStack.begin(); |
| 175 | } |
| 176 | conditional_iterator conditional_end() const { |
| 177 | return ConditionalStack.end(); |
| 178 | } |
Ted Kremenek | 0e977de | 2008-11-12 21:33:59 +0000 | [diff] [blame] | 179 | }; |
| 180 | |
| 181 | } // end namespace clang |
| 182 | |
| 183 | #endif |