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