Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

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