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