//===--- PrintPreprocessedOutput.cpp - Implement the -E mode --------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This code simply runs the preprocessor on the input file and prints out the
// result.  This is the traditional behavior of the -E option.
//
//===----------------------------------------------------------------------===//

#include "clang/Basic/CharInfo.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Frontend/PreprocessorOutputOptions.h"
#include "clang/Frontend/Utils.h"
#include "clang/Lex/MacroInfo.h"
#include "clang/Lex/PPCallbacks.h"
#include "clang/Lex/Pragma.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/TokenConcatenation.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include <cstdio>
using namespace clang;

/// PrintMacroDefinition - Print a macro definition in a form that will be
/// properly accepted back as a definition. If 'II' is nullptr, only the
/// expansion will be printed.
static void PrintMacroDefinition(const IdentifierInfo *II, const MacroInfo &MI,
                                 Preprocessor &PP, raw_ostream *OS) {
  if (II)
    *OS << "#define " << II->getName();

  if (MI.isFunctionLike()) {
    *OS << '(';
    if (!MI.param_empty()) {
      MacroInfo::param_iterator AI = MI.param_begin(), E = MI.param_end();
      for (; AI+1 != E; ++AI) {
        *OS << (*AI)->getName();
        *OS << ',';
      }

      // Last argument.
      if ((*AI)->getName() == "__VA_ARGS__")
        *OS << "...";
      else
        *OS << (*AI)->getName();
    }

    if (MI.isGNUVarargs())
      *OS << "...";  // #define foo(x...)

    *OS << ')';
  }

  // GCC always emits a space, even if the macro body is empty.  However, do not
  // want to emit two spaces if the first token has a leading space.
  if (MI.tokens_empty() || !MI.tokens_begin()->hasLeadingSpace())
    *OS << ' ';

  SmallString<128> SpellingBuffer;
  for (const auto &T : MI.tokens()) {
    if (T.hasLeadingSpace())
      *OS << ' ';

    *OS << PP.getSpelling(T, SpellingBuffer);
  }
}

//===----------------------------------------------------------------------===//
// Preprocessed token printer
//===----------------------------------------------------------------------===//

namespace {
class PrintPPOutputPPCallbacks : public PPCallbacks {
  Preprocessor &PP;
  SourceManager &SM;
  TokenConcatenation ConcatInfo;
public:
  raw_ostream *OS;
private:
  unsigned CurLine;

  bool EmittedTokensOnThisLine;
  bool EmittedDirectiveOnThisLine;
  SrcMgr::CharacteristicKind FileType;
  SmallString<512> CurFilename;
  bool Initialized;
  bool DisableLineMarkers;
  bool DumpDefines;
  bool DumpIncludeDirectives;
  bool DumpEmbedDirectives;
  bool UseLineDirectives;
  bool IsFirstFileEntered;
  bool MinimizeWhitespace;
  bool DirectivesOnly;
  bool KeepSystemIncludes;
  raw_ostream *OrigOS;
  std::unique_ptr<llvm::raw_null_ostream> NullOS;
  unsigned NumToksToSkip;

  Token PrevTok;
  Token PrevPrevTok;

public:
  PrintPPOutputPPCallbacks(Preprocessor &pp, raw_ostream *os, bool lineMarkers,
                           bool defines, bool DumpIncludeDirectives,
                           bool DumpEmbedDirectives, bool UseLineDirectives,
                           bool MinimizeWhitespace, bool DirectivesOnly,
                           bool KeepSystemIncludes)
      : PP(pp), SM(PP.getSourceManager()), ConcatInfo(PP), OS(os),
        DisableLineMarkers(lineMarkers), DumpDefines(defines),
        DumpIncludeDirectives(DumpIncludeDirectives),
        DumpEmbedDirectives(DumpEmbedDirectives),
        UseLineDirectives(UseLineDirectives),
        MinimizeWhitespace(MinimizeWhitespace), DirectivesOnly(DirectivesOnly),
        KeepSystemIncludes(KeepSystemIncludes), OrigOS(os), NumToksToSkip(0) {
    CurLine = 0;
    CurFilename += "<uninit>";
    EmittedTokensOnThisLine = false;
    EmittedDirectiveOnThisLine = false;
    FileType = SrcMgr::C_User;
    Initialized = false;
    IsFirstFileEntered = false;
    if (KeepSystemIncludes)
      NullOS = std::make_unique<llvm::raw_null_ostream>();

    PrevTok.startToken();
    PrevPrevTok.startToken();
  }

  /// Returns true if #embed directives should be expanded into a comma-
  /// delimited list of integer constants or not.
  bool expandEmbedContents() const { return !DumpEmbedDirectives; }

  bool isMinimizeWhitespace() const { return MinimizeWhitespace; }

  void setEmittedTokensOnThisLine() { EmittedTokensOnThisLine = true; }
  bool hasEmittedTokensOnThisLine() const { return EmittedTokensOnThisLine; }

  void setEmittedDirectiveOnThisLine() { EmittedDirectiveOnThisLine = true; }
  bool hasEmittedDirectiveOnThisLine() const {
    return EmittedDirectiveOnThisLine;
  }

  /// Ensure that the output stream position is at the beginning of a new line
  /// and inserts one if it does not. It is intended to ensure that directives
  /// inserted by the directives not from the input source (such as #line) are
  /// in the first column. To insert newlines that represent the input, use
  /// MoveToLine(/*...*/, /*RequireStartOfLine=*/true).
  void startNewLineIfNeeded();

  void FileChanged(SourceLocation Loc, FileChangeReason Reason,
                   SrcMgr::CharacteristicKind FileType,
                   FileID PrevFID) override;
  void EmbedDirective(SourceLocation HashLoc, StringRef FileName, bool IsAngled,
                      OptionalFileEntryRef File,
                      const LexEmbedParametersResult &Params) override;
  void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
                          StringRef FileName, bool IsAngled,
                          CharSourceRange FilenameRange,
                          OptionalFileEntryRef File, StringRef SearchPath,
                          StringRef RelativePath, const Module *SuggestedModule,
                          bool ModuleImported,
                          SrcMgr::CharacteristicKind FileType) override;
  void Ident(SourceLocation Loc, StringRef str) override;
  void PragmaMessage(SourceLocation Loc, StringRef Namespace,
                     PragmaMessageKind Kind, StringRef Str) override;
  void PragmaDebug(SourceLocation Loc, StringRef DebugType) override;
  void PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace) override;
  void PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace) override;
  void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
                        diag::Severity Map, StringRef Str) override;
  void PragmaWarning(SourceLocation Loc, PragmaWarningSpecifier WarningSpec,
                     ArrayRef<int> Ids) override;
  void PragmaWarningPush(SourceLocation Loc, int Level) override;
  void PragmaWarningPop(SourceLocation Loc) override;
  void PragmaExecCharsetPush(SourceLocation Loc, StringRef Str) override;
  void PragmaExecCharsetPop(SourceLocation Loc) override;
  void PragmaAssumeNonNullBegin(SourceLocation Loc) override;
  void PragmaAssumeNonNullEnd(SourceLocation Loc) override;
  void PragmaSetPPState(SourceLocation Loc, IdentifierInfo *MacroName,
                        std::uint64_t Value) override;

  /// Insert whitespace before emitting the next token.
  ///
  /// @param Tok             Next token to be emitted.
  /// @param RequireSpace    Ensure at least one whitespace is emitted. Useful
  ///                        if non-tokens have been emitted to the stream.
  /// @param RequireSameLine Never emit newlines. Useful when semantics depend
  ///                        on being on the same line, such as directives.
  void HandleWhitespaceBeforeTok(const Token &Tok, bool RequireSpace,
                                 bool RequireSameLine);

  /// Move to the line of the provided source location. This will
  /// return true if a newline was inserted or if
  /// the requested location is the first token on the first line.
  /// In these cases the next output will be the first column on the line and
  /// make it possible to insert indention. The newline was inserted
  /// implicitly when at the beginning of the file.
  ///
  /// @param Tok                 Token where to move to.
  /// @param RequireStartOfLine  Whether the next line depends on being in the
  ///                            first column, such as a directive.
  ///
  /// @return Whether column adjustments are necessary.
  bool MoveToLine(const Token &Tok, bool RequireStartOfLine) {
    PresumedLoc PLoc = SM.getPresumedLoc(Tok.getLocation());
    unsigned TargetLine = PLoc.isValid() ? PLoc.getLine() : CurLine;
    bool IsFirstInFile =
        Tok.isAtStartOfLine() && PLoc.isValid() && PLoc.getLine() == 1;
    return MoveToLine(TargetLine, RequireStartOfLine) || IsFirstInFile;
  }

  /// Move to the line of the provided source location. Returns true if a new
  /// line was inserted.
  bool MoveToLine(SourceLocation Loc, bool RequireStartOfLine) {
    PresumedLoc PLoc = SM.getPresumedLoc(Loc);
    unsigned TargetLine = PLoc.isValid() ? PLoc.getLine() : CurLine;
    return MoveToLine(TargetLine, RequireStartOfLine);
  }
  bool MoveToLine(unsigned LineNo, bool RequireStartOfLine);

  bool AvoidConcat(const Token &PrevPrevTok, const Token &PrevTok,
                   const Token &Tok) {
    return ConcatInfo.AvoidConcat(PrevPrevTok, PrevTok, Tok);
  }
  void WriteLineInfo(unsigned LineNo, const char *Extra=nullptr,
                     unsigned ExtraLen=0);
  bool LineMarkersAreDisabled() const { return DisableLineMarkers; }
  void HandleNewlinesInToken(const char *TokStr, unsigned Len);

  /// MacroDefined - This hook is called whenever a macro definition is seen.
  void MacroDefined(const Token &MacroNameTok,
                    const MacroDirective *MD) override;

  /// MacroUndefined - This hook is called whenever a macro #undef is seen.
  void MacroUndefined(const Token &MacroNameTok,
                      const MacroDefinition &MD,
                      const MacroDirective *Undef) override;

  void BeginModule(const Module *M);
  void EndModule(const Module *M);

  unsigned GetNumToksToSkip() const { return NumToksToSkip; }
  void ResetSkipToks() { NumToksToSkip = 0; }

  const Token &GetPrevToken() const { return PrevTok; }
};
}  // end anonymous namespace

void PrintPPOutputPPCallbacks::WriteLineInfo(unsigned LineNo,
                                             const char *Extra,
                                             unsigned ExtraLen) {
  startNewLineIfNeeded();

  // Emit #line directives or GNU line markers depending on what mode we're in.
  if (UseLineDirectives) {
    *OS << "#line" << ' ' << LineNo << ' ' << '"';
    *OS << CurFilename;
    *OS << '"';
  } else {
    *OS << '#' << ' ' << LineNo << ' ' << '"';
    *OS << CurFilename;
    *OS << '"';

    if (ExtraLen)
      OS->write(Extra, ExtraLen);

    if (FileType == SrcMgr::C_System)
      OS->write(" 3", 2);
    else if (FileType == SrcMgr::C_ExternCSystem)
      OS->write(" 3 4", 4);
  }
  *OS << '\n';
}

/// MoveToLine - Move the output to the source line specified by the location
/// object.  We can do this by emitting some number of \n's, or be emitting a
/// #line directive.  This returns false if already at the specified line, true
/// if some newlines were emitted.
bool PrintPPOutputPPCallbacks::MoveToLine(unsigned LineNo,
                                          bool RequireStartOfLine) {
  // If it is required to start a new line or finish the current, insert
  // vertical whitespace now and take it into account when moving to the
  // expected line.
  bool StartedNewLine = false;
  if ((RequireStartOfLine && EmittedTokensOnThisLine) ||
      EmittedDirectiveOnThisLine) {
    *OS << '\n';
    StartedNewLine = true;
    CurLine += 1;
    EmittedTokensOnThisLine = false;
    EmittedDirectiveOnThisLine = false;
  }

  // If this line is "close enough" to the original line, just print newlines,
  // otherwise print a #line directive.
  if (CurLine == LineNo) {
    // Nothing to do if we are already on the correct line.
  } else if (MinimizeWhitespace && DisableLineMarkers) {
    // With -E -P -fminimize-whitespace, don't emit anything if not necessary.
  } else if (!StartedNewLine && LineNo - CurLine == 1) {
    // Printing a single line has priority over printing a #line directive, even
    // when minimizing whitespace which otherwise would print #line directives
    // for every single line.
    *OS << '\n';
    StartedNewLine = true;
  } else if (!DisableLineMarkers) {
    if (LineNo - CurLine <= 8) {
      const char *NewLines = "\n\n\n\n\n\n\n\n";
      OS->write(NewLines, LineNo - CurLine);
    } else {
      // Emit a #line or line marker.
      WriteLineInfo(LineNo, nullptr, 0);
    }
    StartedNewLine = true;
  } else if (EmittedTokensOnThisLine) {
    // If we are not on the correct line and don't need to be line-correct,
    // at least ensure we start on a new line.
    *OS << '\n';
    StartedNewLine = true;
  }

  if (StartedNewLine) {
    EmittedTokensOnThisLine = false;
    EmittedDirectiveOnThisLine = false;
  }

  CurLine = LineNo;
  return StartedNewLine;
}

void PrintPPOutputPPCallbacks::startNewLineIfNeeded() {
  if (EmittedTokensOnThisLine || EmittedDirectiveOnThisLine) {
    *OS << '\n';
    EmittedTokensOnThisLine = false;
    EmittedDirectiveOnThisLine = false;
  }
}

/// FileChanged - Whenever the preprocessor enters or exits a #include file
/// it invokes this handler.  Update our conception of the current source
/// position.
void PrintPPOutputPPCallbacks::FileChanged(SourceLocation Loc,
                                           FileChangeReason Reason,
                                       SrcMgr::CharacteristicKind NewFileType,
                                       FileID PrevFID) {
  // Unless we are exiting a #include, make sure to skip ahead to the line the
  // #include directive was at.
  SourceManager &SourceMgr = SM;

  PresumedLoc UserLoc = SourceMgr.getPresumedLoc(Loc);
  if (UserLoc.isInvalid())
    return;

  unsigned NewLine = UserLoc.getLine();

  if (Reason == PPCallbacks::EnterFile) {
    SourceLocation IncludeLoc = UserLoc.getIncludeLoc();
    if (IncludeLoc.isValid())
      MoveToLine(IncludeLoc, /*RequireStartOfLine=*/false);
  } else if (Reason == PPCallbacks::SystemHeaderPragma) {
    // GCC emits the # directive for this directive on the line AFTER the
    // directive and emits a bunch of spaces that aren't needed. This is because
    // otherwise we will emit a line marker for THIS line, which requires an
    // extra blank line after the directive to avoid making all following lines
    // off by one. We can do better by simply incrementing NewLine here.
    NewLine += 1;
  }

  CurLine = NewLine;

  // In KeepSystemIncludes mode, redirect OS as needed.
  if (KeepSystemIncludes && (isSystem(FileType) != isSystem(NewFileType)))
    OS = isSystem(FileType) ? OrigOS : NullOS.get();

  CurFilename.clear();
  CurFilename += UserLoc.getFilename();
  FileType = NewFileType;

  if (DisableLineMarkers) {
    if (!MinimizeWhitespace)
      startNewLineIfNeeded();
    return;
  }

  if (!Initialized) {
    WriteLineInfo(CurLine);
    Initialized = true;
  }

  // Do not emit an enter marker for the main file (which we expect is the first
  // entered file). This matches gcc, and improves compatibility with some tools
  // which track the # line markers as a way to determine when the preprocessed
  // output is in the context of the main file.
  if (Reason == PPCallbacks::EnterFile && !IsFirstFileEntered) {
    IsFirstFileEntered = true;
    return;
  }

  switch (Reason) {
  case PPCallbacks::EnterFile:
    WriteLineInfo(CurLine, " 1", 2);
    break;
  case PPCallbacks::ExitFile:
    WriteLineInfo(CurLine, " 2", 2);
    break;
  case PPCallbacks::SystemHeaderPragma:
  case PPCallbacks::RenameFile:
    WriteLineInfo(CurLine);
    break;
  }
}

void PrintPPOutputPPCallbacks::EmbedDirective(
    SourceLocation HashLoc, StringRef FileName, bool IsAngled,
    OptionalFileEntryRef File, const LexEmbedParametersResult &Params) {
  if (!DumpEmbedDirectives)
    return;

  // The EmbedDirective() callback is called before we produce the annotation
  // token stream for the directive. We skip printing the annotation tokens
  // within PrintPreprocessedTokens(), but we also need to skip the prefix,
  // suffix, and if_empty tokens as those are inserted directly into the token
  // stream and would otherwise be printed immediately after printing the
  // #embed directive.
  //
  // FIXME: counting tokens to skip is a kludge but we have no way to know
  // which tokens were inserted as part of the embed and which ones were
  // explicitly written by the user.
  MoveToLine(HashLoc, /*RequireStartOfLine=*/true);
  *OS << "#embed " << (IsAngled ? '<' : '"') << FileName
      << (IsAngled ? '>' : '"');

  auto PrintToks = [&](llvm::ArrayRef<Token> Toks) {
    SmallString<128> SpellingBuffer;
    for (const Token &T : Toks) {
      if (T.hasLeadingSpace())
        *OS << " ";
      *OS << PP.getSpelling(T, SpellingBuffer);
    }
  };
  bool SkipAnnotToks = true;
  if (Params.MaybeIfEmptyParam) {
    *OS << " if_empty(";
    PrintToks(Params.MaybeIfEmptyParam->Tokens);
    *OS << ")";
    // If the file is empty, we can skip those tokens. If the file is not
    // empty, we skip the annotation tokens.
    if (File && !File->getSize()) {
      NumToksToSkip += Params.MaybeIfEmptyParam->Tokens.size();
      SkipAnnotToks = false;
    }
  }

  if (Params.MaybeLimitParam) {
    *OS << " limit(" << Params.MaybeLimitParam->Limit << ")";
  }
  if (Params.MaybeOffsetParam) {
    *OS << " clang::offset(" << Params.MaybeOffsetParam->Offset << ")";
  }
  if (Params.MaybePrefixParam) {
    *OS << " prefix(";
    PrintToks(Params.MaybePrefixParam->Tokens);
    *OS << ")";
    NumToksToSkip += Params.MaybePrefixParam->Tokens.size();
  }
  if (Params.MaybeSuffixParam) {
    *OS << " suffix(";
    PrintToks(Params.MaybeSuffixParam->Tokens);
    *OS << ")";
    NumToksToSkip += Params.MaybeSuffixParam->Tokens.size();
  }

  // We may need to skip the annotation token.
  if (SkipAnnotToks)
    NumToksToSkip++;

  *OS << " /* clang -E -dE */";
  setEmittedDirectiveOnThisLine();
}

void PrintPPOutputPPCallbacks::InclusionDirective(
    SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName,
    bool IsAngled, CharSourceRange FilenameRange, OptionalFileEntryRef File,
    StringRef SearchPath, StringRef RelativePath, const Module *SuggestedModule,
    bool ModuleImported, SrcMgr::CharacteristicKind FileType) {
  // In -dI mode, dump #include directives prior to dumping their content or
  // interpretation. Similar for -fkeep-system-includes.
  if (DumpIncludeDirectives || (KeepSystemIncludes && isSystem(FileType))) {
    MoveToLine(HashLoc, /*RequireStartOfLine=*/true);
    const std::string TokenText = PP.getSpelling(IncludeTok);
    assert(!TokenText.empty());
    *OS << "#" << TokenText << " "
        << (IsAngled ? '<' : '"') << FileName << (IsAngled ? '>' : '"')
        << " /* clang -E "
        << (DumpIncludeDirectives ? "-dI" : "-fkeep-system-includes")
        << " */";
    setEmittedDirectiveOnThisLine();
  }

  // When preprocessing, turn implicit imports into module import pragmas.
  if (ModuleImported) {
    switch (IncludeTok.getIdentifierInfo()->getPPKeywordID()) {
    case tok::pp_include:
    case tok::pp_import:
    case tok::pp_include_next:
      MoveToLine(HashLoc, /*RequireStartOfLine=*/true);
      *OS << "#pragma clang module import "
          << SuggestedModule->getFullModuleName(true)
          << " /* clang -E: implicit import for "
          << "#" << PP.getSpelling(IncludeTok) << " "
          << (IsAngled ? '<' : '"') << FileName << (IsAngled ? '>' : '"')
          << " */";
      setEmittedDirectiveOnThisLine();
      break;

    case tok::pp___include_macros:
      // #__include_macros has no effect on a user of a preprocessed source
      // file; the only effect is on preprocessing.
      //
      // FIXME: That's not *quite* true: it causes the module in question to
      // be loaded, which can affect downstream diagnostics.
      break;

    default:
      llvm_unreachable("unknown include directive kind");
      break;
    }
  }
}

/// Handle entering the scope of a module during a module compilation.
void PrintPPOutputPPCallbacks::BeginModule(const Module *M) {
  startNewLineIfNeeded();
  *OS << "#pragma clang module begin " << M->getFullModuleName(true);
  setEmittedDirectiveOnThisLine();
}

/// Handle leaving the scope of a module during a module compilation.
void PrintPPOutputPPCallbacks::EndModule(const Module *M) {
  startNewLineIfNeeded();
  *OS << "#pragma clang module end /*" << M->getFullModuleName(true) << "*/";
  setEmittedDirectiveOnThisLine();
}

/// Ident - Handle #ident directives when read by the preprocessor.
///
void PrintPPOutputPPCallbacks::Ident(SourceLocation Loc, StringRef S) {
  MoveToLine(Loc, /*RequireStartOfLine=*/true);

  OS->write("#ident ", strlen("#ident "));
  OS->write(S.begin(), S.size());
  setEmittedTokensOnThisLine();
}

/// MacroDefined - This hook is called whenever a macro definition is seen.
void PrintPPOutputPPCallbacks::MacroDefined(const Token &MacroNameTok,
                                            const MacroDirective *MD) {
  bool ShouldEmitDefine = true;
  const MacroInfo *MI = MD->getMacroInfo();
  SourceLocation DefLoc = MI->getDefinitionLoc();

  // Print out macro definitions in -dD mode and when we have -fdirectives-only
  // for C++20 header units.
  if ((!DumpDefines && !DirectivesOnly) ||
      // Ignore __FILE__ etc.
      MI->isBuiltinMacro()) {
    ShouldEmitDefine = false;
  } else if (DirectivesOnly && !MI->isUsed()) {
    SourceManager &SM = PP.getSourceManager();
    if (SM.isInPredefinedFile(DefLoc))
      ShouldEmitDefine = false;
  }

  IdentifierInfo *MacroName = MacroNameTok.getIdentifierInfo();
  if (!ShouldEmitDefine) {
    // Preserve macro definitions of macros that can be used with
    // '#pragma clang __set_pp_state' as pragmas if printing '#define's
    // is disabled.
    if (PP.isPragmaSetPPStateMacro(MacroName)) {
      MoveToLine(DefLoc, /*RequireStartOfLine=*/true);
      *OS << "#pragma clang __set_pp_state " << MacroName->getName();
      PrintMacroDefinition(/*II=*/nullptr, *MI, PP, OS);
      setEmittedDirectiveOnThisLine();
    }
    return;
  }

  MoveToLine(DefLoc, /*RequireStartOfLine=*/true);
  PrintMacroDefinition(MacroName, *MI, PP, OS);
  setEmittedDirectiveOnThisLine();
}

void PrintPPOutputPPCallbacks::MacroUndefined(const Token &MacroNameTok,
                                              const MacroDefinition &MD,
                                              const MacroDirective *Undef) {
  // Print out macro definitions in -dD mode and when we have -fdirectives-only
  // for C++20 header units.
  if (!DumpDefines && !DirectivesOnly)
    return;

  MoveToLine(MacroNameTok.getLocation(), /*RequireStartOfLine=*/true);
  *OS << "#undef " << MacroNameTok.getIdentifierInfo()->getName();
  setEmittedDirectiveOnThisLine();
}

static void outputPrintable(raw_ostream *OS, StringRef Str) {
  for (unsigned char Char : Str) {
    if (isPrintable(Char) && Char != '\\' && Char != '"')
      *OS << (char)Char;
    else // Output anything hard as an octal escape.
      *OS << '\\'
          << (char)('0' + ((Char >> 6) & 7))
          << (char)('0' + ((Char >> 3) & 7))
          << (char)('0' + ((Char >> 0) & 7));
  }
}

void PrintPPOutputPPCallbacks::PragmaMessage(SourceLocation Loc,
                                             StringRef Namespace,
                                             PragmaMessageKind Kind,
                                             StringRef Str) {
  MoveToLine(Loc, /*RequireStartOfLine=*/true);
  *OS << "#pragma ";
  if (!Namespace.empty())
    *OS << Namespace << ' ';
  switch (Kind) {
    case PMK_Message:
      *OS << "message(\"";
      break;
    case PMK_Warning:
      *OS << "warning \"";
      break;
    case PMK_Error:
      *OS << "error \"";
      break;
  }

  outputPrintable(OS, Str);
  *OS << '"';
  if (Kind == PMK_Message)
    *OS << ')';
  setEmittedDirectiveOnThisLine();
}

void PrintPPOutputPPCallbacks::PragmaDebug(SourceLocation Loc,
                                           StringRef DebugType) {
  MoveToLine(Loc, /*RequireStartOfLine=*/true);

  *OS << "#pragma clang __debug ";
  *OS << DebugType;

  setEmittedDirectiveOnThisLine();
}

void PrintPPOutputPPCallbacks::
PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace) {
  MoveToLine(Loc, /*RequireStartOfLine=*/true);
  *OS << "#pragma " << Namespace << " diagnostic push";
  setEmittedDirectiveOnThisLine();
}

void PrintPPOutputPPCallbacks::
PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace) {
  MoveToLine(Loc, /*RequireStartOfLine=*/true);
  *OS << "#pragma " << Namespace << " diagnostic pop";
  setEmittedDirectiveOnThisLine();
}

void PrintPPOutputPPCallbacks::PragmaDiagnostic(SourceLocation Loc,
                                                StringRef Namespace,
                                                diag::Severity Map,
                                                StringRef Str) {
  MoveToLine(Loc, /*RequireStartOfLine=*/true);
  *OS << "#pragma " << Namespace << " diagnostic ";
  switch (Map) {
  case diag::Severity::Remark:
    *OS << "remark";
    break;
  case diag::Severity::Warning:
    *OS << "warning";
    break;
  case diag::Severity::Error:
    *OS << "error";
    break;
  case diag::Severity::Ignored:
    *OS << "ignored";
    break;
  case diag::Severity::Fatal:
    *OS << "fatal";
    break;
  }
  *OS << " \"" << Str << '"';
  setEmittedDirectiveOnThisLine();
}

void PrintPPOutputPPCallbacks::PragmaWarning(SourceLocation Loc,
                                             PragmaWarningSpecifier WarningSpec,
                                             ArrayRef<int> Ids) {
  MoveToLine(Loc, /*RequireStartOfLine=*/true);

  *OS << "#pragma warning(";
  switch(WarningSpec) {
    case PWS_Default:  *OS << "default"; break;
    case PWS_Disable:  *OS << "disable"; break;
    case PWS_Error:    *OS << "error"; break;
    case PWS_Once:     *OS << "once"; break;
    case PWS_Suppress: *OS << "suppress"; break;
    case PWS_Level1:   *OS << '1'; break;
    case PWS_Level2:   *OS << '2'; break;
    case PWS_Level3:   *OS << '3'; break;
    case PWS_Level4:   *OS << '4'; break;
  }
  *OS << ':';

  for (ArrayRef<int>::iterator I = Ids.begin(), E = Ids.end(); I != E; ++I)
    *OS << ' ' << *I;
  *OS << ')';
  setEmittedDirectiveOnThisLine();
}

void PrintPPOutputPPCallbacks::PragmaWarningPush(SourceLocation Loc,
                                                 int Level) {
  MoveToLine(Loc, /*RequireStartOfLine=*/true);
  *OS << "#pragma warning(push";
  if (Level >= 0)
    *OS << ", " << Level;
  *OS << ')';
  setEmittedDirectiveOnThisLine();
}

void PrintPPOutputPPCallbacks::PragmaWarningPop(SourceLocation Loc) {
  MoveToLine(Loc, /*RequireStartOfLine=*/true);
  *OS << "#pragma warning(pop)";
  setEmittedDirectiveOnThisLine();
}

void PrintPPOutputPPCallbacks::PragmaExecCharsetPush(SourceLocation Loc,
                                                     StringRef Str) {
  MoveToLine(Loc, /*RequireStartOfLine=*/true);
  *OS << "#pragma character_execution_set(push";
  if (!Str.empty())
    *OS << ", " << Str;
  *OS << ')';
  setEmittedDirectiveOnThisLine();
}

void PrintPPOutputPPCallbacks::PragmaExecCharsetPop(SourceLocation Loc) {
  MoveToLine(Loc, /*RequireStartOfLine=*/true);
  *OS << "#pragma character_execution_set(pop)";
  setEmittedDirectiveOnThisLine();
}

void PrintPPOutputPPCallbacks::
PragmaAssumeNonNullBegin(SourceLocation Loc) {
  MoveToLine(Loc, /*RequireStartOfLine=*/true);
  *OS << "#pragma clang assume_nonnull begin";
  setEmittedDirectiveOnThisLine();
}

void PrintPPOutputPPCallbacks::
PragmaAssumeNonNullEnd(SourceLocation Loc) {
  MoveToLine(Loc, /*RequireStartOfLine=*/true);
  *OS << "#pragma clang assume_nonnull end";
  setEmittedDirectiveOnThisLine();
}

void PrintPPOutputPPCallbacks::PragmaSetPPState(SourceLocation Loc,
                                                IdentifierInfo *MacroName,
                                                std::uint64_t Value) {
  MoveToLine(Loc, /*RequireStartOfLine=*/true);
  *OS << "#pragma clang __set_pp_state " << MacroName->getName() << " "
      << Value;
  setEmittedDirectiveOnThisLine();
}

void PrintPPOutputPPCallbacks::HandleWhitespaceBeforeTok(const Token &Tok,
                                                         bool RequireSpace,
                                                         bool RequireSameLine) {
  // These tokens are not expanded to anything and don't need whitespace before
  // them.
  if (Tok.is(tok::eof) ||
      (Tok.isAnnotation() && !Tok.is(tok::annot_header_unit) &&
       !Tok.is(tok::annot_module_begin) && !Tok.is(tok::annot_module_end) &&
       !Tok.is(tok::annot_repl_input_end) && !Tok.is(tok::annot_embed) &&
       !Tok.is(tok::annot_module_name)))
    return;

  // EmittedDirectiveOnThisLine takes priority over RequireSameLine.
  if ((!RequireSameLine || EmittedDirectiveOnThisLine) &&
      MoveToLine(Tok, /*RequireStartOfLine=*/EmittedDirectiveOnThisLine)) {
    if (MinimizeWhitespace) {
      // Avoid interpreting hash as a directive under -fpreprocessed.
      if (Tok.is(tok::hash))
        *OS << ' ';
    } else {
      // Print out space characters so that the first token on a line is
      // indented for easy reading.
      unsigned ColNo = SM.getExpansionColumnNumber(Tok.getLocation());

      // The first token on a line can have a column number of 1, yet still
      // expect leading white space, if a macro expansion in column 1 starts
      // with an empty macro argument, or an empty nested macro expansion. In
      // this case, move the token to column 2.
      if (ColNo == 1 && Tok.hasLeadingSpace())
        ColNo = 2;

      // This hack prevents stuff like:
      // #define HASH #
      // HASH define foo bar
      // From having the # character end up at column 1, which makes it so it
      // is not handled as a #define next time through the preprocessor if in
      // -fpreprocessed mode.
      if (ColNo <= 1 && Tok.is(tok::hash))
        *OS << ' ';

      // Otherwise, indent the appropriate number of spaces.
      for (; ColNo > 1; --ColNo)
        *OS << ' ';
    }
  } else {
    // Insert whitespace between the previous and next token if either
    // - The caller requires it
    // - The input had whitespace between them and we are not in
    //   whitespace-minimization mode
    // - The whitespace is necessary to keep the tokens apart and there is not
    //   already a newline between them
    if (RequireSpace || (!MinimizeWhitespace && Tok.hasLeadingSpace()) ||
        ((EmittedTokensOnThisLine || EmittedDirectiveOnThisLine) &&
         AvoidConcat(PrevPrevTok, PrevTok, Tok)))
      *OS << ' ';
  }

  PrevPrevTok = PrevTok;
  PrevTok = Tok;
}

void PrintPPOutputPPCallbacks::HandleNewlinesInToken(const char *TokStr,
                                                     unsigned Len) {
  unsigned NumNewlines = 0;
  for (; Len; --Len, ++TokStr) {
    if (*TokStr != '\n' &&
        *TokStr != '\r')
      continue;

    ++NumNewlines;

    // If we have \n\r or \r\n, skip both and count as one line.
    if (Len != 1 &&
        (TokStr[1] == '\n' || TokStr[1] == '\r') &&
        TokStr[0] != TokStr[1]) {
      ++TokStr;
      --Len;
    }
  }

  if (NumNewlines == 0) return;

  CurLine += NumNewlines;
}


namespace {
struct UnknownPragmaHandler : public PragmaHandler {
  const char *Prefix;
  PrintPPOutputPPCallbacks *Callbacks;

  // Set to true if tokens should be expanded
  bool ShouldExpandTokens;

  UnknownPragmaHandler(const char *prefix, PrintPPOutputPPCallbacks *callbacks,
                       bool RequireTokenExpansion)
      : Prefix(prefix), Callbacks(callbacks),
        ShouldExpandTokens(RequireTokenExpansion) {}
  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
                    Token &PragmaTok) override {
    // Figure out what line we went to and insert the appropriate number of
    // newline characters.
    Callbacks->MoveToLine(PragmaTok.getLocation(), /*RequireStartOfLine=*/true);
    Callbacks->OS->write(Prefix, strlen(Prefix));
    Callbacks->setEmittedTokensOnThisLine();

    if (ShouldExpandTokens) {
      // The first token does not have expanded macros. Expand them, if
      // required.
      auto Toks = std::make_unique<Token[]>(1);
      Toks[0] = PragmaTok;
      PP.EnterTokenStream(std::move(Toks), /*NumToks=*/1,
                          /*DisableMacroExpansion=*/false,
                          /*IsReinject=*/false);
      PP.Lex(PragmaTok);
    }

    // Read and print all of the pragma tokens.
    bool IsFirst = true;
    while (PragmaTok.isNot(tok::eod)) {
      Callbacks->HandleWhitespaceBeforeTok(PragmaTok, /*RequireSpace=*/IsFirst,
                                           /*RequireSameLine=*/true);
      IsFirst = false;
      std::string TokSpell = PP.getSpelling(PragmaTok);
      Callbacks->OS->write(&TokSpell[0], TokSpell.size());
      Callbacks->setEmittedTokensOnThisLine();

      if (ShouldExpandTokens)
        PP.Lex(PragmaTok);
      else
        PP.LexUnexpandedToken(PragmaTok);
    }
    Callbacks->setEmittedDirectiveOnThisLine();
  }
};
} // end anonymous namespace


static void PrintPreprocessedTokens(Preprocessor &PP, Token &Tok,
                                    PrintPPOutputPPCallbacks *Callbacks) {
  bool DropComments = PP.getLangOpts().TraditionalCPP &&
                      !PP.getCommentRetentionState();

  bool IsStartOfLine = false;
  bool IsCXXModuleDirective = false;
  char Buffer[256];
  while (true) {
    // Two lines joined with line continuation ('\' as last character on the
    // line) must be emitted as one line even though Tok.getLine() returns two
    // different values. In this situation Tok.isAtStartOfLine() is false even
    // though it may be the first token on the lexical line. When
    // dropping/skipping a token that is at the start of a line, propagate the
    // start-of-line-ness to the next token to not append it to the previous
    // line.
    IsStartOfLine = IsStartOfLine || Tok.isAtStartOfLine();

    Callbacks->HandleWhitespaceBeforeTok(Tok, /*RequireSpace=*/false,
                                         /*RequireSameLine=*/!IsStartOfLine);

    if (DropComments && Tok.is(tok::comment)) {
      // Skip comments. Normally the preprocessor does not generate
      // tok::comment nodes at all when not keeping comments, but under
      // -traditional-cpp the lexer keeps /all/ whitespace, including comments.
      PP.Lex(Tok);
      continue;
    } else if (Tok.is(tok::annot_repl_input_end)) {
      // Fall through to exit the loop.
    } else if (Tok.is(tok::eod)) {
      // Don't print end of directive tokens, since they are typically newlines
      // that mess up our line tracking. These come from unknown pre-processor
      // directives or hash-prefixed comments in standalone assembly files.
      PP.Lex(Tok);
      // FIXME: The token on the next line after #include should have
      // Tok.isAtStartOfLine() set.
      IsStartOfLine = true;
      continue;
    } else if (Tok.is(tok::annot_module_include)) {
      // PrintPPOutputPPCallbacks::InclusionDirective handles producing
      // appropriate output here. Ignore this token entirely.
      PP.Lex(Tok);
      IsStartOfLine = true;
      continue;
    } else if (Tok.is(tok::annot_module_begin)) {
      // FIXME: We retrieve this token after the FileChanged callback, and
      // retrieve the module_end token before the FileChanged callback, so
      // we render this within the file and render the module end outside the
      // file, but this is backwards from the token locations: the module_begin
      // token is at the include location (outside the file) and the module_end
      // token is at the EOF location (within the file).
      Callbacks->BeginModule(
          reinterpret_cast<Module *>(Tok.getAnnotationValue()));
      PP.Lex(Tok);
      IsStartOfLine = true;
      continue;
    } else if (Tok.is(tok::annot_module_end)) {
      Callbacks->EndModule(
          reinterpret_cast<Module *>(Tok.getAnnotationValue()));
      PP.Lex(Tok);
      IsStartOfLine = true;
      continue;
    } else if (Tok.is(tok::annot_header_unit)) {
      // This is a header-name that has been (effectively) converted into a
      // module-name, print them inside quote.
      // FIXME: The module name could contain non-identifier module name
      // components and OS specific file paths components. We don't have a good
      // way to round-trip those.
      Module *M = reinterpret_cast<Module *>(Tok.getAnnotationValue());
      std::string Name = M->getFullModuleName();
      *Callbacks->OS << '"';
      Callbacks->OS->write_escaped(Name);
      *Callbacks->OS << '"';
    } else if (Tok.is(tok::annot_embed)) {
      // Manually explode the binary data out to a stream of comma-delimited
      // integer values. If the user passed -dE, that is handled by the
      // EmbedDirective() callback. We should only get here if the user did not
      // pass -dE.
      assert(Callbacks->expandEmbedContents() &&
             "did not expect an embed annotation");
      auto *Data =
          reinterpret_cast<EmbedAnnotationData *>(Tok.getAnnotationValue());

      // Loop over the contents and print them as a comma-delimited list of
      // values.
      bool PrintComma = false;
      for (unsigned char Byte : Data->BinaryData.bytes()) {
        if (PrintComma)
          *Callbacks->OS << ", ";
        *Callbacks->OS << static_cast<int>(Byte);
        PrintComma = true;
      }
    } else if (Tok.is(tok::annot_module_name)) {
      auto *NameLoc = static_cast<ModuleNameLoc *>(Tok.getAnnotationValue());
      *Callbacks->OS << NameLoc->str();
    } else if (Tok.isAnnotation()) {
      // Ignore annotation tokens created by pragmas - the pragmas themselves
      // will be reproduced in the preprocessed output.
      PP.Lex(Tok);
      continue;
    } else if (PP.getLangOpts().CPlusPlusModules && Tok.is(tok::kw_import) &&
               !Callbacks->GetPrevToken().is(tok::at)) {
      assert(!IsCXXModuleDirective && "Is an import directive being printed?");
      IsCXXModuleDirective = true;
      IsStartOfLine = false;
      *Callbacks->OS << tok::getPPKeywordSpelling(
          tok::pp___preprocessed_import);
      PP.Lex(Tok);
      continue;
    } else if (PP.getLangOpts().CPlusPlusModules && Tok.is(tok::kw_module)) {
      assert(!IsCXXModuleDirective && "Is an module directive being printed?");
      IsCXXModuleDirective = true;
      IsStartOfLine = false;
      *Callbacks->OS << tok::getPPKeywordSpelling(
          tok::pp___preprocessed_module);
      PP.Lex(Tok);
      continue;
    } else if (PP.getLangOpts().CPlusPlusModules && IsCXXModuleDirective &&
               Tok.is(tok::semi)) {
      IsCXXModuleDirective = false;
      IsStartOfLine = true;
      *Callbacks->OS << ';';
      PP.Lex(Tok);
      continue;
    } else if (IdentifierInfo *II = Tok.getIdentifierInfo()) {
      *Callbacks->OS << II->getName();
    } else if (Tok.isLiteral() && !Tok.needsCleaning() &&
               Tok.getLiteralData()) {
      Callbacks->OS->write(Tok.getLiteralData(), Tok.getLength());
    } else if (Tok.getLength() < std::size(Buffer)) {
      const char *TokPtr = Buffer;
      unsigned Len = PP.getSpelling(Tok, TokPtr);
      Callbacks->OS->write(TokPtr, Len);

      // Tokens that can contain embedded newlines need to adjust our current
      // line number.
      // FIXME: The token may end with a newline in which case
      // setEmittedDirectiveOnThisLine/setEmittedTokensOnThisLine afterwards is
      // wrong.
      if (Tok.getKind() == tok::comment || Tok.getKind() == tok::unknown)
        Callbacks->HandleNewlinesInToken(TokPtr, Len);
      if (Tok.is(tok::comment) && Len >= 2 && TokPtr[0] == '/' &&
          TokPtr[1] == '/') {
        // It's a line comment;
        // Ensure that we don't concatenate anything behind it.
        Callbacks->setEmittedDirectiveOnThisLine();
      }
    } else {
      std::string S = PP.getSpelling(Tok);
      Callbacks->OS->write(S.data(), S.size());

      // Tokens that can contain embedded newlines need to adjust our current
      // line number.
      if (Tok.getKind() == tok::comment || Tok.getKind() == tok::unknown)
        Callbacks->HandleNewlinesInToken(S.data(), S.size());
      if (Tok.is(tok::comment) && S.size() >= 2 && S[0] == '/' && S[1] == '/') {
        // It's a line comment;
        // Ensure that we don't concatenate anything behind it.
        Callbacks->setEmittedDirectiveOnThisLine();
      }
    }
    Callbacks->setEmittedTokensOnThisLine();
    IsStartOfLine = false;

    if (Tok.is(tok::eof) || Tok.is(tok::annot_repl_input_end))
      break;

    PP.Lex(Tok);
    // If lexing that token causes us to need to skip future tokens, do so now.
    for (unsigned I = 0, Skip = Callbacks->GetNumToksToSkip(); I < Skip; ++I)
      PP.Lex(Tok);
    Callbacks->ResetSkipToks();
  }
}

typedef std::pair<const IdentifierInfo *, MacroInfo *> id_macro_pair;
static int MacroIDCompare(const id_macro_pair *LHS, const id_macro_pair *RHS) {
  return LHS->first->getName().compare(RHS->first->getName());
}

static void DoPrintMacros(Preprocessor &PP, raw_ostream *OS) {
  // Ignore unknown pragmas.
  PP.IgnorePragmas();

  // -dM mode just scans and ignores all tokens in the files, then dumps out
  // the macro table at the end.
  PP.EnterMainSourceFile();

  PP.LexTokensUntilEOF();

  SmallVector<id_macro_pair, 128> MacrosByID;
  for (const auto &M : PP.macros()) {
    auto *MD = M.second.getLatest();
    if (MD && MD->isDefined())
      MacrosByID.push_back(id_macro_pair(M.first, MD->getMacroInfo()));
  }
  llvm::array_pod_sort(MacrosByID.begin(), MacrosByID.end(), MacroIDCompare);

  for (unsigned i = 0, e = MacrosByID.size(); i != e; ++i) {
    MacroInfo &MI = *MacrosByID[i].second;
    // Ignore computed macros like __LINE__ and friends.
    if (MI.isBuiltinMacro()) continue;

    PrintMacroDefinition(MacrosByID[i].first, MI, PP, OS);
    *OS << '\n';
  }
}

/// DoPrintPreprocessedInput - This implements -E mode.
///
void clang::DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream *OS,
                                     const PreprocessorOutputOptions &Opts) {
  // Show macros with no output is handled specially.
  if (!Opts.ShowCPP) {
    assert(Opts.ShowMacros && "Not yet implemented!");
    DoPrintMacros(PP, OS);
    return;
  }

  // Inform the preprocessor whether we want it to retain comments or not, due
  // to -C or -CC.
  PP.SetCommentRetentionState(Opts.ShowComments, Opts.ShowMacroComments);

  PrintPPOutputPPCallbacks *Callbacks = new PrintPPOutputPPCallbacks(
      PP, OS, !Opts.ShowLineMarkers, Opts.ShowMacros,
      Opts.ShowIncludeDirectives, Opts.ShowEmbedDirectives,
      Opts.UseLineDirectives, Opts.MinimizeWhitespace, Opts.DirectivesOnly,
      Opts.KeepSystemIncludes);

  // Expand macros in pragmas with -fms-extensions.  The assumption is that
  // the majority of pragmas in such a file will be Microsoft pragmas.
  // Remember the handlers we will add so that we can remove them later.
  std::unique_ptr<UnknownPragmaHandler> MicrosoftExtHandler(
      new UnknownPragmaHandler(
          "#pragma", Callbacks,
          /*RequireTokenExpansion=*/PP.getLangOpts().MicrosoftExt));

  std::unique_ptr<UnknownPragmaHandler> GCCHandler(new UnknownPragmaHandler(
      "#pragma GCC", Callbacks,
      /*RequireTokenExpansion=*/PP.getLangOpts().MicrosoftExt));

  std::unique_ptr<UnknownPragmaHandler> ClangHandler(new UnknownPragmaHandler(
      "#pragma clang", Callbacks,
      /*RequireTokenExpansion=*/PP.getLangOpts().MicrosoftExt));

  PP.AddPragmaHandler(MicrosoftExtHandler.get());
  PP.AddPragmaHandler("GCC", GCCHandler.get());
  PP.AddPragmaHandler("clang", ClangHandler.get());

  // The tokens after pragma omp need to be expanded.
  //
  //  OpenMP [2.1, Directive format]
  //  Preprocessing tokens following the #pragma omp are subject to macro
  //  replacement.
  std::unique_ptr<UnknownPragmaHandler> OpenMPHandler(
      new UnknownPragmaHandler("#pragma omp", Callbacks,
                               /*RequireTokenExpansion=*/true));
  PP.AddPragmaHandler("omp", OpenMPHandler.get());

  PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(Callbacks));

  // After we have configured the preprocessor, enter the main file.
  PP.EnterMainSourceFile();
  if (Opts.DirectivesOnly)
    PP.SetMacroExpansionOnlyInDirectives();

  // Consume all of the tokens that come from the predefines buffer.  Those
  // should not be emitted into the output and are guaranteed to be at the
  // start.
  const SourceManager &SourceMgr = PP.getSourceManager();
  Token Tok;
  do {
    PP.Lex(Tok);
    if (Tok.is(tok::eof) || !Tok.getLocation().isFileID())
      break;

    PresumedLoc PLoc = SourceMgr.getPresumedLoc(Tok.getLocation());
    if (PLoc.isInvalid())
      break;

    if (strcmp(PLoc.getFilename(), "<built-in>"))
      break;
  } while (true);

  // Read all the preprocessed tokens, printing them out to the stream.
  PrintPreprocessedTokens(PP, Tok, Callbacks);
  *OS << '\n';

  // Remove the handlers we just added to leave the preprocessor in a sane state
  // so that it can be reused (for example by a clang::Parser instance).
  PP.RemovePragmaHandler(MicrosoftExtHandler.get());
  PP.RemovePragmaHandler("GCC", GCCHandler.get());
  PP.RemovePragmaHandler("clang", ClangHandler.get());
  PP.RemovePragmaHandler("omp", OpenMPHandler.get());
}
