clang API Documentation
00001 //===--- PreprocessorLexer.h - C Language Family Lexer ----------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines the PreprocessorLexer interface. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_CLANG_PreprocessorLexer_H 00015 #define LLVM_CLANG_PreprocessorLexer_H 00016 00017 #include "clang/Lex/MultipleIncludeOpt.h" 00018 #include "clang/Lex/Token.h" 00019 #include "llvm/ADT/SmallVector.h" 00020 00021 namespace clang { 00022 00023 class FileEntry; 00024 class Preprocessor; 00025 00026 class PreprocessorLexer { 00027 virtual void anchor(); 00028 protected: 00029 Preprocessor *PP; // Preprocessor object controlling lexing. 00030 00031 /// The SourceManager FileID corresponding to the file being lexed. 00032 const FileID FID; 00033 00034 /// \brief Number of SLocEntries before lexing the file. 00035 unsigned InitialNumSLocEntries; 00036 00037 //===--------------------------------------------------------------------===// 00038 // Context-specific lexing flags set by the preprocessor. 00039 //===--------------------------------------------------------------------===// 00040 00041 /// ParsingPreprocessorDirective - This is true when parsing #XXX. This turns 00042 /// '\n' into a tok::eod token. 00043 bool ParsingPreprocessorDirective; 00044 00045 /// ParsingFilename - True after #include: this turns <xx> into a 00046 /// tok::angle_string_literal token. 00047 bool ParsingFilename; 00048 00049 /// LexingRawMode - True if in raw mode: This flag disables interpretation of 00050 /// tokens and is a far faster mode to lex in than non-raw-mode. This flag: 00051 /// 1. If EOF of the current lexer is found, the include stack isn't popped. 00052 /// 2. Identifier information is not looked up for identifier tokens. As an 00053 /// effect of this, implicit macro expansion is naturally disabled. 00054 /// 3. "#" tokens at the start of a line are treated as normal tokens, not 00055 /// implicitly transformed by the lexer. 00056 /// 4. All diagnostic messages are disabled. 00057 /// 5. No callbacks are made into the preprocessor. 00058 /// 00059 /// Note that in raw mode that the PP pointer may be null. 00060 bool LexingRawMode; 00061 00062 /// MIOpt - This is a state machine that detects the #ifndef-wrapping a file 00063 /// idiom for the multiple-include optimization. 00064 MultipleIncludeOpt MIOpt; 00065 00066 /// ConditionalStack - Information about the set of #if/#ifdef/#ifndef blocks 00067 /// we are currently in. 00068 SmallVector<PPConditionalInfo, 4> ConditionalStack; 00069 00070 PreprocessorLexer(const PreprocessorLexer&); // DO NOT IMPLEMENT 00071 void operator=(const PreprocessorLexer&); // DO NOT IMPLEMENT 00072 friend class Preprocessor; 00073 00074 PreprocessorLexer(Preprocessor *pp, FileID fid); 00075 00076 PreprocessorLexer() 00077 : PP(0), InitialNumSLocEntries(0), 00078 ParsingPreprocessorDirective(false), 00079 ParsingFilename(false), 00080 LexingRawMode(false) {} 00081 00082 virtual ~PreprocessorLexer() {} 00083 00084 virtual void IndirectLex(Token& Result) = 0; 00085 00086 /// getSourceLocation - Return the source location for the next observable 00087 /// location. 00088 virtual SourceLocation getSourceLocation() = 0; 00089 00090 //===--------------------------------------------------------------------===// 00091 // #if directive handling. 00092 00093 /// pushConditionalLevel - When we enter a #if directive, this keeps track of 00094 /// what we are currently in for diagnostic emission (e.g. #if with missing 00095 /// #endif). 00096 void pushConditionalLevel(SourceLocation DirectiveStart, bool WasSkipping, 00097 bool FoundNonSkip, bool FoundElse) { 00098 PPConditionalInfo CI; 00099 CI.IfLoc = DirectiveStart; 00100 CI.WasSkipping = WasSkipping; 00101 CI.FoundNonSkip = FoundNonSkip; 00102 CI.FoundElse = FoundElse; 00103 ConditionalStack.push_back(CI); 00104 } 00105 void pushConditionalLevel(const PPConditionalInfo &CI) { 00106 ConditionalStack.push_back(CI); 00107 } 00108 00109 /// popConditionalLevel - Remove an entry off the top of the conditional 00110 /// stack, returning information about it. If the conditional stack is empty, 00111 /// this returns true and does not fill in the arguments. 00112 bool popConditionalLevel(PPConditionalInfo &CI) { 00113 if (ConditionalStack.empty()) return true; 00114 CI = ConditionalStack.back(); 00115 ConditionalStack.pop_back(); 00116 return false; 00117 } 00118 00119 /// peekConditionalLevel - Return the top of the conditional stack. This 00120 /// requires that there be a conditional active. 00121 PPConditionalInfo &peekConditionalLevel() { 00122 assert(!ConditionalStack.empty() && "No conditionals active!"); 00123 return ConditionalStack.back(); 00124 } 00125 00126 unsigned getConditionalStackDepth() const { return ConditionalStack.size(); } 00127 00128 public: 00129 00130 //===--------------------------------------------------------------------===// 00131 // Misc. lexing methods. 00132 00133 /// LexIncludeFilename - After the preprocessor has parsed a #include, lex and 00134 /// (potentially) macro expand the filename. If the sequence parsed is not 00135 /// lexically legal, emit a diagnostic and return a result EOD token. 00136 void LexIncludeFilename(Token &Result); 00137 00138 /// setParsingPreprocessorDirective - Inform the lexer whether or not 00139 /// we are currently lexing a preprocessor directive. 00140 void setParsingPreprocessorDirective(bool f) { 00141 ParsingPreprocessorDirective = f; 00142 } 00143 00144 /// isLexingRawMode - Return true if this lexer is in raw mode or not. 00145 bool isLexingRawMode() const { return LexingRawMode; } 00146 00147 /// getPP - Return the preprocessor object for this lexer. 00148 Preprocessor *getPP() const { return PP; } 00149 00150 FileID getFileID() const { 00151 assert(PP && 00152 "PreprocessorLexer::getFileID() should only be used with a Preprocessor"); 00153 return FID; 00154 } 00155 00156 /// \brief Number of SLocEntries before lexing the file. 00157 unsigned getInitialNumSLocEntries() const { 00158 return InitialNumSLocEntries; 00159 } 00160 00161 /// getFileEntry - Return the FileEntry corresponding to this FileID. Like 00162 /// getFileID(), this only works for lexers with attached preprocessors. 00163 const FileEntry *getFileEntry() const; 00164 00165 /// \brief Iterator that traverses the current stack of preprocessor 00166 /// conditional directives (#if/#ifdef/#ifndef). 00167 typedef SmallVectorImpl<PPConditionalInfo>::const_iterator 00168 conditional_iterator; 00169 00170 conditional_iterator conditional_begin() const { 00171 return ConditionalStack.begin(); 00172 } 00173 conditional_iterator conditional_end() const { 00174 return ConditionalStack.end(); 00175 } 00176 }; 00177 00178 } // end namespace clang 00179 00180 #endif