Home | History | Annotate | Download | only in Lex
      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 /// \file
     11 /// \brief Defines the PreprocessorLexer interface.
     12 ///
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LLVM_CLANG_PreprocessorLexer_H
     16 #define LLVM_CLANG_PreprocessorLexer_H
     17 
     18 #include "clang/Lex/MultipleIncludeOpt.h"
     19 #include "clang/Lex/Token.h"
     20 #include "llvm/ADT/SmallVector.h"
     21 
     22 namespace clang {
     23 
     24 class FileEntry;
     25 class Preprocessor;
     26 
     27 class PreprocessorLexer {
     28   virtual void anchor();
     29 protected:
     30   Preprocessor *PP;              // Preprocessor object controlling lexing.
     31 
     32   /// The SourceManager FileID corresponding to the file being lexed.
     33   const FileID FID;
     34 
     35   /// \brief Number of SLocEntries before lexing the file.
     36   unsigned InitialNumSLocEntries;
     37 
     38   //===--------------------------------------------------------------------===//
     39   // Context-specific lexing flags set by the preprocessor.
     40   //===--------------------------------------------------------------------===//
     41 
     42   /// \brief True when parsing \#XXX; turns '\\n' into a tok::eod token.
     43   bool ParsingPreprocessorDirective;
     44 
     45   /// \brief True after \#include; turns \<xx> into a tok::angle_string_literal
     46   /// token.
     47   bool ParsingFilename;
     48 
     49   /// \brief True if in raw mode.
     50   ///
     51   /// Raw mode disables interpretation of tokens and is a far faster mode to
     52   /// lex in than non-raw-mode.  This flag:
     53   ///  1. If EOF of the current lexer is found, the include stack isn't popped.
     54   ///  2. Identifier information is not looked up for identifier tokens.  As an
     55   ///     effect of this, implicit macro expansion is naturally disabled.
     56   ///  3. "#" tokens at the start of a line are treated as normal tokens, not
     57   ///     implicitly transformed by the lexer.
     58   ///  4. All diagnostic messages are disabled.
     59   ///  5. No callbacks are made into the preprocessor.
     60   ///
     61   /// Note that in raw mode that the PP pointer may be null.
     62   bool LexingRawMode;
     63 
     64   /// \brief A state machine that detects the \#ifndef-wrapping a file
     65   /// idiom for the multiple-include optimization.
     66   MultipleIncludeOpt MIOpt;
     67 
     68   /// \brief Information about the set of \#if/\#ifdef/\#ifndef blocks
     69   /// we are currently in.
     70   SmallVector<PPConditionalInfo, 4> ConditionalStack;
     71 
     72   PreprocessorLexer(const PreprocessorLexer &) LLVM_DELETED_FUNCTION;
     73   void operator=(const PreprocessorLexer &) LLVM_DELETED_FUNCTION;
     74   friend class Preprocessor;
     75 
     76   PreprocessorLexer(Preprocessor *pp, FileID fid);
     77 
     78   PreprocessorLexer()
     79     : PP(0), InitialNumSLocEntries(0),
     80       ParsingPreprocessorDirective(false),
     81       ParsingFilename(false),
     82       LexingRawMode(false) {}
     83 
     84   virtual ~PreprocessorLexer() {}
     85 
     86   virtual void IndirectLex(Token& Result) = 0;
     87 
     88   /// \brief Return the source location for the next observable location.
     89   virtual SourceLocation getSourceLocation() = 0;
     90 
     91   //===--------------------------------------------------------------------===//
     92   // #if directive handling.
     93 
     94   /// pushConditionalLevel - When we enter a \#if directive, this keeps track of
     95   /// what we are currently in for diagnostic emission (e.g. \#if with missing
     96   /// \#endif).
     97   void pushConditionalLevel(SourceLocation DirectiveStart, bool WasSkipping,
     98                             bool FoundNonSkip, bool FoundElse) {
     99     PPConditionalInfo CI;
    100     CI.IfLoc = DirectiveStart;
    101     CI.WasSkipping = WasSkipping;
    102     CI.FoundNonSkip = FoundNonSkip;
    103     CI.FoundElse = FoundElse;
    104     ConditionalStack.push_back(CI);
    105   }
    106   void pushConditionalLevel(const PPConditionalInfo &CI) {
    107     ConditionalStack.push_back(CI);
    108   }
    109 
    110   /// popConditionalLevel - Remove an entry off the top of the conditional
    111   /// stack, returning information about it.  If the conditional stack is empty,
    112   /// this returns true and does not fill in the arguments.
    113   bool popConditionalLevel(PPConditionalInfo &CI) {
    114     if (ConditionalStack.empty()) return true;
    115     CI = ConditionalStack.back();
    116     ConditionalStack.pop_back();
    117     return false;
    118   }
    119 
    120   /// \brief Return the top of the conditional stack.
    121   /// \pre This requires that there be a conditional active.
    122   PPConditionalInfo &peekConditionalLevel() {
    123     assert(!ConditionalStack.empty() && "No conditionals active!");
    124     return ConditionalStack.back();
    125   }
    126 
    127   unsigned getConditionalStackDepth() const { return ConditionalStack.size(); }
    128 
    129 public:
    130 
    131   //===--------------------------------------------------------------------===//
    132   // Misc. lexing methods.
    133 
    134   /// \brief After the preprocessor has parsed a \#include, lex and
    135   /// (potentially) macro expand the filename.
    136   ///
    137   /// If the sequence parsed is not lexically legal, emit a diagnostic and
    138   /// return a result EOD token.
    139   void LexIncludeFilename(Token &Result);
    140 
    141   /// \brief Inform the lexer whether or not we are currently lexing a
    142   /// preprocessor directive.
    143   void setParsingPreprocessorDirective(bool f) {
    144     ParsingPreprocessorDirective = f;
    145   }
    146 
    147   /// \brief Return true if this lexer is in raw mode or not.
    148   bool isLexingRawMode() const { return LexingRawMode; }
    149 
    150   /// \brief Return the preprocessor object for this lexer.
    151   Preprocessor *getPP() const { return PP; }
    152 
    153   FileID getFileID() const {
    154     assert(PP &&
    155       "PreprocessorLexer::getFileID() should only be used with a Preprocessor");
    156     return FID;
    157   }
    158 
    159   /// \brief Number of SLocEntries before lexing the file.
    160   unsigned getInitialNumSLocEntries() const {
    161     return InitialNumSLocEntries;
    162   }
    163 
    164   /// getFileEntry - Return the FileEntry corresponding to this FileID.  Like
    165   /// getFileID(), this only works for lexers with attached preprocessors.
    166   const FileEntry *getFileEntry() const;
    167 
    168   /// \brief Iterator that traverses the current stack of preprocessor
    169   /// conditional directives (\#if/\#ifdef/\#ifndef).
    170   typedef SmallVectorImpl<PPConditionalInfo>::const_iterator
    171     conditional_iterator;
    172 
    173   conditional_iterator conditional_begin() const {
    174     return ConditionalStack.begin();
    175   }
    176   conditional_iterator conditional_end() const {
    177     return ConditionalStack.end();
    178   }
    179 };
    180 
    181 }  // end namespace clang
    182 
    183 #endif
    184