clang API Documentation

PreprocessorLexer.h
Go to the documentation of this file.
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