//===- PreprocessorLexer.h - C Language Family Lexer ------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
/// \file
/// Defines the PreprocessorLexer interface.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_LEX_PREPROCESSORLEXER_H
#define LLVM_CLANG_LEX_PREPROCESSORLEXER_H

#include "clang/Basic/SourceLocation.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/MultipleIncludeOpt.h"
#include "clang/Lex/Token.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include <cassert>

namespace clang {

class FileEntry;
class Preprocessor;

class PreprocessorLexer {
  virtual void anchor();

protected:
  friend class Preprocessor;

  // Preprocessor object controlling lexing.
  Preprocessor *PP = nullptr;

  /// The SourceManager FileID corresponding to the file being lexed.
  const FileID FID;

  /// Number of SLocEntries before lexing the file.
  unsigned InitialNumSLocEntries = 0;

  //===--------------------------------------------------------------------===//
  // Context-specific lexing flags set by the preprocessor.
  //===--------------------------------------------------------------------===//

  /// True when parsing \#XXX; turns '\\n' into a tok::eod token.
  bool ParsingPreprocessorDirective = false;

  /// True after \#include; turns \<xx> or "xxx" into a tok::header_name token.
  bool ParsingFilename = false;

  /// True if in raw mode.
  ///
  /// Raw mode disables interpretation of tokens and is a far faster mode to
  /// lex in than non-raw-mode.  This flag:
  ///  1. If EOF of the current lexer is found, the include stack isn't popped.
  ///  2. Identifier information is not looked up for identifier tokens.  As an
  ///     effect of this, implicit macro expansion is naturally disabled.
  ///  3. "#" tokens at the start of a line are treated as normal tokens, not
  ///     implicitly transformed by the lexer.
  ///  4. All diagnostic messages are disabled.
  ///  5. No callbacks are made into the preprocessor.
  ///
  /// Note that in raw mode that the PP pointer may be null.
  bool LexingRawMode = false;

  /// A state machine that detects the \#ifndef-wrapping a file
  /// idiom for the multiple-include optimization.
  MultipleIncludeOpt MIOpt;

  /// Information about the set of \#if/\#ifdef/\#ifndef blocks
  /// we are currently in.
  SmallVector<PPConditionalInfo, 4> ConditionalStack;

  struct IncludeInfo {
    const FileEntry *File;
    SourceLocation Location;
  };
  // A complete history of all the files included by the current file.
  llvm::StringMap<IncludeInfo> IncludeHistory;

  PreprocessorLexer() : FID() {}
  PreprocessorLexer(Preprocessor *pp, FileID fid);
  virtual ~PreprocessorLexer() = default;

  virtual void IndirectLex(Token& Result) = 0;

  /// Return the source location for the next observable location.
  virtual SourceLocation getSourceLocation() = 0;

  //===--------------------------------------------------------------------===//
  // #if directive handling.

  /// pushConditionalLevel - When we enter a \#if directive, this keeps track of
  /// what we are currently in for diagnostic emission (e.g. \#if with missing
  /// \#endif).
  void pushConditionalLevel(SourceLocation DirectiveStart, bool WasSkipping,
                            bool FoundNonSkip, bool FoundElse) {
    PPConditionalInfo CI;
    CI.IfLoc = DirectiveStart;
    CI.WasSkipping = WasSkipping;
    CI.FoundNonSkip = FoundNonSkip;
    CI.FoundElse = FoundElse;
    ConditionalStack.push_back(CI);
  }
  void pushConditionalLevel(const PPConditionalInfo &CI) {
    ConditionalStack.push_back(CI);
  }

  /// popConditionalLevel - Remove an entry off the top of the conditional
  /// stack, returning information about it.  If the conditional stack is empty,
  /// this returns true and does not fill in the arguments.
  bool popConditionalLevel(PPConditionalInfo &CI) {
    if (ConditionalStack.empty())
      return true;
    CI = ConditionalStack.pop_back_val();
    return false;
  }

  /// Return the top of the conditional stack.
  /// \pre This requires that there be a conditional active.
  PPConditionalInfo &peekConditionalLevel() {
    assert(!ConditionalStack.empty() && "No conditionals active!");
    return ConditionalStack.back();
  }

  unsigned getConditionalStackDepth() const { return ConditionalStack.size(); }

public:
  PreprocessorLexer(const PreprocessorLexer &) = delete;
  PreprocessorLexer &operator=(const PreprocessorLexer &) = delete;

  //===--------------------------------------------------------------------===//
  // Misc. lexing methods.

  /// Lex a token, producing a header-name token if possible.
  void LexIncludeFilename(Token &FilenameTok);

  /// Inform the lexer whether or not we are currently lexing a
  /// preprocessor directive.
  void setParsingPreprocessorDirective(bool f) {
    ParsingPreprocessorDirective = f;
  }

  /// Return true if this lexer is in raw mode or not.
  bool isLexingRawMode() const { return LexingRawMode; }

  /// Return the preprocessor object for this lexer.
  Preprocessor *getPP() const { return PP; }

  FileID getFileID() const {
    assert(PP &&
      "PreprocessorLexer::getFileID() should only be used with a Preprocessor");
    return FID;
  }

  /// Number of SLocEntries before lexing the file.
  unsigned getInitialNumSLocEntries() const {
    return InitialNumSLocEntries;
  }

  /// getFileEntry - Return the FileEntry corresponding to this FileID.  Like
  /// getFileID(), this only works for lexers with attached preprocessors.
  const FileEntry *getFileEntry() const;

  /// Iterator that traverses the current stack of preprocessor
  /// conditional directives (\#if/\#ifdef/\#ifndef).
  using conditional_iterator =
      SmallVectorImpl<PPConditionalInfo>::const_iterator;

  conditional_iterator conditional_begin() const {
    return ConditionalStack.begin();
  }

  conditional_iterator conditional_end() const {
    return ConditionalStack.end();
  }

  void setConditionalLevels(ArrayRef<PPConditionalInfo> CL) {
    ConditionalStack.clear();
    ConditionalStack.append(CL.begin(), CL.end());
  }

  void addInclude(StringRef Filename, const FileEntry &File,
                  SourceLocation Location) {
    IncludeHistory.insert({Filename, {&File, Location}});
  }

  const llvm::StringMap<IncludeInfo> &getIncludeHistory() const {
    return IncludeHistory;
  }
};

} // namespace clang

#endif // LLVM_CLANG_LEX_PREPROCESSORLEXER_H
