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 //  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