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