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