24#include "llvm/ADT/STLExtras.h" 
   25#include "llvm/ADT/StringRef.h" 
   26#include "llvm/Support/ErrorHandling.h" 
   27#include "llvm/Support/raw_ostream.h" 
   35  *OS << 
"#define " << II.
getName();
 
   41      for (; AI+1 != E; ++AI) {
 
   42        *OS << (*AI)->getName();
 
   47      if ((*AI)->getName() == 
"__VA_ARGS__")
 
   50        *OS << (*AI)->getName();
 
   65  for (
const auto &
T : MI.
tokens()) {
 
   66    if (
T.hasLeadingSpace())
 
 
   78class PrintPPOutputPPCallbacks : 
public PPCallbacks {
 
   81  TokenConcatenation ConcatInfo;
 
   87  bool EmittedTokensOnThisLine;
 
   88  bool EmittedDirectiveOnThisLine;
 
   90  SmallString<512> CurFilename;
 
   92  bool DisableLineMarkers;
 
   94  bool DumpIncludeDirectives;
 
   95  bool DumpEmbedDirectives;
 
   96  bool UseLineDirectives;
 
   97  bool IsFirstFileEntered;
 
   98  bool MinimizeWhitespace;
 
  100  bool KeepSystemIncludes;
 
  102  std::unique_ptr<llvm::raw_null_ostream> NullOS;
 
  103  unsigned NumToksToSkip;
 
  109  PrintPPOutputPPCallbacks(Preprocessor &pp, raw_ostream *os, 
bool lineMarkers,
 
  110                           bool defines, 
bool DumpIncludeDirectives,
 
  111                           bool DumpEmbedDirectives, 
bool UseLineDirectives,
 
  112                           bool MinimizeWhitespace, 
bool DirectivesOnly,
 
  113                           bool KeepSystemIncludes)
 
  114      : PP(pp), SM(PP.getSourceManager()), ConcatInfo(PP), OS(os),
 
  115        DisableLineMarkers(lineMarkers), DumpDefines(defines),
 
  116        DumpIncludeDirectives(DumpIncludeDirectives),
 
  117        DumpEmbedDirectives(DumpEmbedDirectives),
 
  118        UseLineDirectives(UseLineDirectives),
 
  119        MinimizeWhitespace(MinimizeWhitespace), DirectivesOnly(DirectivesOnly),
 
  120        KeepSystemIncludes(KeepSystemIncludes), OrigOS(os), NumToksToSkip(0) {
 
  122    CurFilename += 
"<uninit>";
 
  123    EmittedTokensOnThisLine = 
false;
 
  124    EmittedDirectiveOnThisLine = 
false;
 
  127    IsFirstFileEntered = 
false;
 
  128    if (KeepSystemIncludes)
 
  129      NullOS = std::make_unique<llvm::raw_null_ostream>();
 
  131    PrevTok.startToken();
 
  132    PrevPrevTok.startToken();
 
  137  bool expandEmbedContents()
 const { 
return !DumpEmbedDirectives; }
 
  139  bool isMinimizeWhitespace()
 const { 
return MinimizeWhitespace; }
 
  141  void setEmittedTokensOnThisLine() { EmittedTokensOnThisLine = 
true; }
 
  142  bool hasEmittedTokensOnThisLine()
 const { 
return EmittedTokensOnThisLine; }
 
  144  void setEmittedDirectiveOnThisLine() { EmittedDirectiveOnThisLine = 
true; }
 
  145  bool hasEmittedDirectiveOnThisLine()
 const {
 
  146    return EmittedDirectiveOnThisLine;
 
  154  void startNewLineIfNeeded();
 
  156  void FileChanged(SourceLocation Loc, FileChangeReason Reason,
 
  158                   FileID PrevFID) 
override;
 
  159  void EmbedDirective(SourceLocation HashLoc, StringRef 
FileName, 
bool IsAngled,
 
  161                      const LexEmbedParametersResult &Params) 
override;
 
  162  void InclusionDirective(SourceLocation HashLoc, 
const Token &IncludeTok,
 
  164                          CharSourceRange FilenameRange,
 
  166                          StringRef RelativePath, 
const Module *SuggestedModule,
 
  169  void Ident(SourceLocation Loc, StringRef str) 
override;
 
  170  void PragmaMessage(SourceLocation Loc, StringRef Namespace,
 
  171                     PragmaMessageKind Kind, StringRef Str) 
override;
 
  172  void PragmaDebug(SourceLocation Loc, StringRef DebugType) 
override;
 
  173  void PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace) 
override;
 
  174  void PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace) 
override;
 
  175  void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
 
  177  void PragmaWarning(SourceLocation Loc, PragmaWarningSpecifier WarningSpec,
 
  178                     ArrayRef<int> Ids) 
override;
 
  179  void PragmaWarningPush(SourceLocation Loc, 
int Level) 
override;
 
  180  void PragmaWarningPop(SourceLocation Loc) 
override;
 
  181  void PragmaExecCharsetPush(SourceLocation Loc, StringRef Str) 
override;
 
  182  void PragmaExecCharsetPop(SourceLocation Loc) 
override;
 
  183  void PragmaAssumeNonNullBegin(SourceLocation Loc) 
override;
 
  184  void PragmaAssumeNonNullEnd(SourceLocation Loc) 
override;
 
  193  void HandleWhitespaceBeforeTok(
const Token &
Tok, 
bool RequireSpace,
 
  194                                 bool RequireSameLine);
 
  208  bool MoveToLine(
const Token &
Tok, 
bool RequireStartOfLine) {
 
  213    return MoveToLine(TargetLine, RequireStartOfLine) || IsFirstInFile;
 
  218  bool MoveToLine(SourceLocation Loc, 
bool RequireStartOfLine) {
 
  219    PresumedLoc PLoc = SM.getPresumedLoc(Loc);
 
  221    return MoveToLine(TargetLine, RequireStartOfLine);
 
  223  bool MoveToLine(
unsigned LineNo, 
bool RequireStartOfLine);
 
  225  bool AvoidConcat(
const Token &PrevPrevTok, 
const Token &PrevTok,
 
  227    return ConcatInfo.AvoidConcat(PrevPrevTok, PrevTok, 
Tok);
 
  229  void WriteLineInfo(
unsigned LineNo, 
const char *
Extra=
nullptr,
 
  230                     unsigned ExtraLen=0);
 
  231  bool LineMarkersAreDisabled()
 const { 
return DisableLineMarkers; }
 
  232  void HandleNewlinesInToken(
const char *TokStr, 
unsigned Len);
 
  235  void MacroDefined(
const Token &MacroNameTok,
 
  236                    const MacroDirective *MD) 
override;
 
  239  void MacroUndefined(
const Token &MacroNameTok,
 
  240                      const MacroDefinition &MD,
 
  241                      const MacroDirective *Undef) 
override;
 
  243  void BeginModule(
const Module *M);
 
  244  void EndModule(
const Module *M);
 
  246  unsigned GetNumToksToSkip()
 const { 
return NumToksToSkip; }
 
  247  void ResetSkipToks() { NumToksToSkip = 0; }
 
  251void PrintPPOutputPPCallbacks::WriteLineInfo(
unsigned LineNo,
 
  254  startNewLineIfNeeded();
 
  257  if (UseLineDirectives) {
 
  258    *
OS << 
"#line" << 
' ' << LineNo << 
' ' << 
'"';
 
  259    OS->write_escaped(CurFilename);
 
  262    *
OS << 
'#' << 
' ' << LineNo << 
' ' << 
'"';
 
  263    OS->write_escaped(CurFilename);
 
  272      OS->write(
" 3 4", 4);
 
  281bool PrintPPOutputPPCallbacks::MoveToLine(
unsigned LineNo,
 
  282                                          bool RequireStartOfLine) {
 
  286  bool StartedNewLine = 
false;
 
  287  if ((RequireStartOfLine && EmittedTokensOnThisLine) ||
 
  288      EmittedDirectiveOnThisLine) {
 
  290    StartedNewLine = 
true;
 
  292    EmittedTokensOnThisLine = 
false;
 
  293    EmittedDirectiveOnThisLine = 
false;
 
  298  if (CurLine == LineNo) {
 
  300  } 
else if (MinimizeWhitespace && DisableLineMarkers) {
 
  302  } 
else if (!StartedNewLine && LineNo - CurLine == 1) {
 
  307    StartedNewLine = 
true;
 
  308  } 
else if (!DisableLineMarkers) {
 
  309    if (LineNo - CurLine <= 8) {
 
  310      const char *NewLines = 
"\n\n\n\n\n\n\n\n";
 
  311      OS->write(NewLines, LineNo - CurLine);
 
  314      WriteLineInfo(LineNo, 
nullptr, 0);
 
  316    StartedNewLine = 
true;
 
  317  } 
else if (EmittedTokensOnThisLine) {
 
  321    StartedNewLine = 
true;
 
  324  if (StartedNewLine) {
 
  325    EmittedTokensOnThisLine = 
false;
 
  326    EmittedDirectiveOnThisLine = 
false;
 
  330  return StartedNewLine;
 
  333void PrintPPOutputPPCallbacks::startNewLineIfNeeded() {
 
  334  if (EmittedTokensOnThisLine || EmittedDirectiveOnThisLine) {
 
  336    EmittedTokensOnThisLine = 
false;
 
  337    EmittedDirectiveOnThisLine = 
false;
 
  344void PrintPPOutputPPCallbacks::FileChanged(SourceLocation Loc,
 
  345                                           FileChangeReason Reason,
 
  350  SourceManager &SourceMgr = 
SM;
 
  356  unsigned NewLine = UserLoc.
getLine();
 
  361      MoveToLine(IncludeLoc, 
false);
 
  381  if (DisableLineMarkers) {
 
  382    if (!MinimizeWhitespace)
 
  383      startNewLineIfNeeded();
 
  388    WriteLineInfo(CurLine);
 
  397    IsFirstFileEntered = 
true;
 
  403    WriteLineInfo(CurLine, 
" 1", 2);
 
  406    WriteLineInfo(CurLine, 
" 2", 2);
 
  410    WriteLineInfo(CurLine);
 
  415void PrintPPOutputPPCallbacks::EmbedDirective(
 
  416    SourceLocation HashLoc, StringRef 
FileName, 
bool IsAngled,
 
  418  if (!DumpEmbedDirectives)
 
  431  MoveToLine(HashLoc, 
true);
 
  432  *
OS << 
"#embed " << (IsAngled ? 
'<' : 
'"') << 
FileName 
  433      << (IsAngled ? 
'>' : 
'"');
 
  435  auto PrintToks = [&](llvm::ArrayRef<Token> Toks) {
 
  436    SmallString<128> SpellingBuffer;
 
  437    for (
const Token &
T : Toks) {
 
  438      if (
T.hasLeadingSpace())
 
  443  bool SkipAnnotToks = 
true;
 
  452      SkipAnnotToks = 
false;
 
  479  *
OS << 
" /* clang -E -dE */";
 
  480  setEmittedDirectiveOnThisLine();
 
  483void PrintPPOutputPPCallbacks::InclusionDirective(
 
  484    SourceLocation HashLoc, 
const Token &IncludeTok, StringRef 
FileName,
 
  486    StringRef SearchPath, StringRef RelativePath, 
const Module *SuggestedModule,
 
  491    MoveToLine(HashLoc, 
true);
 
  495        << (IsAngled ? 
'<' : 
'"') << 
FileName << (IsAngled ? 
'>' : 
'"')
 
  497        << (DumpIncludeDirectives ? 
"-dI" : 
"-fkeep-system-includes")
 
  499    setEmittedDirectiveOnThisLine();
 
  503  if (ModuleImported) {
 
  505    case tok::pp_include:
 
  507    case tok::pp_include_next:
 
  508      MoveToLine(HashLoc, 
true);
 
  509      *
OS << 
"#pragma clang module import " 
  511          << 
" /* clang -E: implicit import for " 
  513          << (IsAngled ? 
'<' : 
'"') << 
FileName << (IsAngled ? 
'>' : 
'"')
 
  515      setEmittedDirectiveOnThisLine();
 
  518    case tok::pp___include_macros:
 
  527      llvm_unreachable(
"unknown include directive kind");
 
  534void PrintPPOutputPPCallbacks::BeginModule(
const Module *M) {
 
  535  startNewLineIfNeeded();
 
  537  setEmittedDirectiveOnThisLine();
 
  541void PrintPPOutputPPCallbacks::EndModule(
const Module *M) {
 
  542  startNewLineIfNeeded();
 
  544  setEmittedDirectiveOnThisLine();
 
  549void PrintPPOutputPPCallbacks::Ident(SourceLocation Loc, StringRef S) {
 
  550  MoveToLine(Loc, 
true);
 
  552  OS->write(
"#ident ", strlen(
"#ident "));
 
  553  OS->write(S.begin(), S.size());
 
  554  setEmittedTokensOnThisLine();
 
  558void PrintPPOutputPPCallbacks::MacroDefined(
const Token &MacroNameTok,
 
  559                                            const MacroDirective *MD) {
 
  563  if ((!DumpDefines && !DirectivesOnly) ||
 
  569  if (DirectivesOnly && !MI->
isUsed()) {
 
  571    if (
SM.isInPredefinedFile(DefLoc))
 
  574  MoveToLine(DefLoc, 
true);
 
  576  setEmittedDirectiveOnThisLine();
 
  579void PrintPPOutputPPCallbacks::MacroUndefined(
const Token &MacroNameTok,
 
  580                                              const MacroDefinition &MD,
 
  581                                              const MacroDirective *Undef) {
 
  584  if (!DumpDefines && !DirectivesOnly)
 
  589  setEmittedDirectiveOnThisLine();
 
  593  for (
unsigned char Char : Str) {
 
  594    if (
isPrintable(Char) && Char != 
'\\' && Char != 
'"')
 
  598          << (char)(
'0' + ((Char >> 6) & 7))
 
  599          << (char)(
'0' + ((Char >> 3) & 7))
 
  600          << (char)(
'0' + ((Char >> 0) & 7));
 
 
  604void PrintPPOutputPPCallbacks::PragmaMessage(SourceLocation Loc,
 
  606                                             PragmaMessageKind Kind,
 
  608  MoveToLine(Loc, 
true);
 
  626  if (Kind == PMK_Message)
 
  628  setEmittedDirectiveOnThisLine();
 
  631void PrintPPOutputPPCallbacks::PragmaDebug(SourceLocation Loc,
 
  632                                           StringRef DebugType) {
 
  633  MoveToLine(Loc, 
true);
 
  635  *
OS << 
"#pragma clang __debug ";
 
  638  setEmittedDirectiveOnThisLine();
 
  641void PrintPPOutputPPCallbacks::
 
  642PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace) {
 
  643  MoveToLine(Loc, 
true);
 
  644  *
OS << 
"#pragma " << 
Namespace << 
" diagnostic push";
 
  645  setEmittedDirectiveOnThisLine();
 
  648void PrintPPOutputPPCallbacks::
 
  649PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace) {
 
  650  MoveToLine(Loc, 
true);
 
  651  *
OS << 
"#pragma " << 
Namespace << 
" diagnostic pop";
 
  652  setEmittedDirectiveOnThisLine();
 
  655void PrintPPOutputPPCallbacks::PragmaDiagnostic(SourceLocation Loc,
 
  659  MoveToLine(Loc, 
true);
 
  662  case diag::Severity::Remark:
 
  665  case diag::Severity::Warning:
 
  668  case diag::Severity::Error:
 
  671  case diag::Severity::Ignored:
 
  674  case diag::Severity::Fatal:
 
  678  *
OS << 
" \"" << Str << 
'"';
 
  679  setEmittedDirectiveOnThisLine();
 
  682void PrintPPOutputPPCallbacks::PragmaWarning(SourceLocation Loc,
 
  683                                             PragmaWarningSpecifier WarningSpec,
 
  685  MoveToLine(Loc, 
true);
 
  687  *
OS << 
"#pragma warning(";
 
  688  switch(WarningSpec) {
 
  689    case PWS_Default:  *
OS << 
"default"; 
break;
 
  690    case PWS_Disable:  *
OS << 
"disable"; 
break;
 
  691    case PWS_Error:    *
OS << 
"error"; 
break;
 
  692    case PWS_Once:     *
OS << 
"once"; 
break;
 
  693    case PWS_Suppress: *
OS << 
"suppress"; 
break;
 
  694    case PWS_Level1:   *
OS << 
'1'; 
break;
 
  695    case PWS_Level2:   *
OS << 
'2'; 
break;
 
  696    case PWS_Level3:   *
OS << 
'3'; 
break;
 
  697    case PWS_Level4:   *
OS << 
'4'; 
break;
 
  701  for (ArrayRef<int>::iterator I = Ids.begin(), E = Ids.end(); I != E; ++I)
 
  704  setEmittedDirectiveOnThisLine();
 
  707void PrintPPOutputPPCallbacks::PragmaWarningPush(SourceLocation Loc,
 
  709  MoveToLine(Loc, 
true);
 
  710  *
OS << 
"#pragma warning(push";
 
  714  setEmittedDirectiveOnThisLine();
 
  717void PrintPPOutputPPCallbacks::PragmaWarningPop(SourceLocation Loc) {
 
  718  MoveToLine(Loc, 
true);
 
  719  *
OS << 
"#pragma warning(pop)";
 
  720  setEmittedDirectiveOnThisLine();
 
  723void PrintPPOutputPPCallbacks::PragmaExecCharsetPush(SourceLocation Loc,
 
  725  MoveToLine(Loc, 
true);
 
  726  *
OS << 
"#pragma character_execution_set(push";
 
  730  setEmittedDirectiveOnThisLine();
 
  733void PrintPPOutputPPCallbacks::PragmaExecCharsetPop(SourceLocation Loc) {
 
  734  MoveToLine(Loc, 
true);
 
  735  *
OS << 
"#pragma character_execution_set(pop)";
 
  736  setEmittedDirectiveOnThisLine();
 
  739void PrintPPOutputPPCallbacks::
 
  740PragmaAssumeNonNullBegin(SourceLocation Loc) {
 
  741  MoveToLine(Loc, 
true);
 
  742  *
OS << 
"#pragma clang assume_nonnull begin";
 
  743  setEmittedDirectiveOnThisLine();
 
  746void PrintPPOutputPPCallbacks::
 
  747PragmaAssumeNonNullEnd(SourceLocation Loc) {
 
  748  MoveToLine(Loc, 
true);
 
  749  *
OS << 
"#pragma clang assume_nonnull end";
 
  750  setEmittedDirectiveOnThisLine();
 
  753void PrintPPOutputPPCallbacks::HandleWhitespaceBeforeTok(
const Token &
Tok,
 
  755                                                         bool RequireSameLine) {
 
  758  if (
Tok.
is(tok::eof) ||
 
  760       !
Tok.
is(tok::annot_module_begin) && !
Tok.
is(tok::annot_module_end) &&
 
  761       !
Tok.
is(tok::annot_repl_input_end) && !
Tok.
is(tok::annot_embed)))
 
  765  if ((!RequireSameLine || EmittedDirectiveOnThisLine) &&
 
  766      MoveToLine(
Tok, EmittedDirectiveOnThisLine)) {
 
  767    if (MinimizeWhitespace) {
 
  769      if (
Tok.
is(tok::hash))
 
  789      if (ColNo <= 1 && 
Tok.
is(tok::hash))
 
  793      for (; ColNo > 1; --ColNo)
 
  804        ((EmittedTokensOnThisLine || EmittedDirectiveOnThisLine) &&
 
  805         AvoidConcat(PrevPrevTok, PrevTok, 
Tok)))
 
  809  PrevPrevTok = PrevTok;
 
  813void PrintPPOutputPPCallbacks::HandleNewlinesInToken(
const char *TokStr,
 
  815  unsigned NumNewlines = 0;
 
  816  for (; Len; --Len, ++TokStr) {
 
  817    if (*TokStr != 
'\n' &&
 
  825        (TokStr[1] == 
'\n' || TokStr[1] == 
'\r') &&
 
  826        TokStr[0] != TokStr[1]) {
 
  832  if (NumNewlines == 0) 
return;
 
  834  CurLine += NumNewlines;
 
  839struct UnknownPragmaHandler : 
public PragmaHandler {
 
  841  PrintPPOutputPPCallbacks *Callbacks;
 
  844  bool ShouldExpandTokens;
 
  846  UnknownPragmaHandler(
const char *prefix, PrintPPOutputPPCallbacks *callbacks,
 
  847                       bool RequireTokenExpansion)
 
  848      : Prefix(prefix), Callbacks(callbacks),
 
  849        ShouldExpandTokens(RequireTokenExpansion) {}
 
  850  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
 
  851                    Token &PragmaTok)
 override {
 
  854    Callbacks->MoveToLine(PragmaTok.
getLocation(), 
true);
 
  855    Callbacks->OS->write(Prefix, strlen(Prefix));
 
  856    Callbacks->setEmittedTokensOnThisLine();
 
  858    if (ShouldExpandTokens) {
 
  861      auto Toks = std::make_unique<Token[]>(1);
 
  863      PP.EnterTokenStream(std::move(Toks), 1,
 
  871    while (PragmaTok.
isNot(tok::eod)) {
 
  872      Callbacks->HandleWhitespaceBeforeTok(PragmaTok, 
IsFirst,
 
  876      Callbacks->OS->write(&TokSpell[0], TokSpell.size());
 
  877      Callbacks->setEmittedTokensOnThisLine();
 
  879      if (ShouldExpandTokens)
 
  884    Callbacks->setEmittedDirectiveOnThisLine();
 
  891                                    PrintPPOutputPPCallbacks *Callbacks) {
 
  892  bool DropComments = PP.
getLangOpts().TraditionalCPP &&
 
  895  bool IsStartOfLine = 
false;
 
  905    IsStartOfLine = IsStartOfLine || 
Tok.isAtStartOfLine();
 
  907    Callbacks->HandleWhitespaceBeforeTok(
Tok, 
false,
 
  910    if (DropComments && 
Tok.is(tok::comment)) {
 
  916    } 
else if (
Tok.is(tok::annot_repl_input_end)) {
 
  918    } 
else if (
Tok.is(tok::eod)) {
 
  925      IsStartOfLine = 
true;
 
  927    } 
else if (
Tok.is(tok::annot_module_include)) {
 
  931      IsStartOfLine = 
true;
 
  933    } 
else if (
Tok.is(tok::annot_module_begin)) {
 
  940      Callbacks->BeginModule(
 
  941          reinterpret_cast<Module *
>(
Tok.getAnnotationValue()));
 
  943      IsStartOfLine = 
true;
 
  945    } 
else if (
Tok.is(tok::annot_module_end)) {
 
  946      Callbacks->EndModule(
 
  947          reinterpret_cast<Module *
>(
Tok.getAnnotationValue()));
 
  949      IsStartOfLine = 
true;
 
  951    } 
else if (
Tok.is(tok::annot_header_unit)) {
 
  959      *Callbacks->OS << 
'"';
 
  960      Callbacks->OS->write_escaped(Name);
 
  961      *Callbacks->OS << 
'"';
 
  962    } 
else if (
Tok.is(tok::annot_embed)) {
 
  967      assert(Callbacks->expandEmbedContents() &&
 
  968             "did not expect an embed annotation");
 
  974      bool PrintComma = 
false;
 
  975      for (
unsigned char Byte : 
Data->BinaryData.bytes()) {
 
  977          *Callbacks->OS << 
", ";
 
  978        *Callbacks->OS << 
static_cast<int>(Byte);
 
  981    } 
else if (
Tok.isAnnotation()) {
 
  987      *Callbacks->OS << II->getName();
 
  988    } 
else if (
Tok.isLiteral() && !
Tok.needsCleaning() &&
 
  989               Tok.getLiteralData()) {
 
  990      Callbacks->OS->write(
Tok.getLiteralData(), 
Tok.getLength());
 
  991    } 
else if (
Tok.getLength() < std::size(Buffer)) {
 
  992      const char *TokPtr = Buffer;
 
  994      Callbacks->OS->write(TokPtr, Len);
 
 1001      if (
Tok.getKind() == tok::comment || 
Tok.getKind() == tok::unknown)
 
 1002        Callbacks->HandleNewlinesInToken(TokPtr, Len);
 
 1003      if (
Tok.is(tok::comment) && Len >= 2 && TokPtr[0] == 
'/' &&
 
 1007        Callbacks->setEmittedDirectiveOnThisLine();
 
 1011      Callbacks->OS->write(S.data(), S.size());
 
 1015      if (
Tok.getKind() == tok::comment || 
Tok.getKind() == tok::unknown)
 
 1016        Callbacks->HandleNewlinesInToken(S.data(), S.size());
 
 1017      if (
Tok.is(tok::comment) && S.size() >= 2 && S[0] == 
'/' && S[1] == 
'/') {
 
 1020        Callbacks->setEmittedDirectiveOnThisLine();
 
 1023    Callbacks->setEmittedTokensOnThisLine();
 
 1024    IsStartOfLine = 
false;
 
 1026    if (
Tok.is(tok::eof) || 
Tok.is(tok::annot_repl_input_end))
 
 1031    for (
unsigned I = 0, 
Skip = Callbacks->GetNumToksToSkip(); I < 
Skip; ++I)
 
 1033    Callbacks->ResetSkipToks();
 
 
 1039  return LHS->first->getName().compare(RHS->first->getName());
 
 
 1055    auto *MD = I->second.getLatest();
 
 1056    if (MD && MD->isDefined())
 
 1059  llvm::array_pod_sort(MacrosByID.begin(), MacrosByID.end(), 
MacroIDCompare);
 
 1061  for (
unsigned i = 0, e = MacrosByID.size(); i != e; ++i) {
 
 
 1077    assert(Opts.
ShowMacros && 
"Not yet implemented!");
 
 1086  PrintPPOutputPPCallbacks *Callbacks = 
new PrintPPOutputPPCallbacks(
 
 1095  std::unique_ptr<UnknownPragmaHandler> MicrosoftExtHandler(
 
 1096      new UnknownPragmaHandler(
 
 1097          "#pragma", Callbacks,
 
 1100  std::unique_ptr<UnknownPragmaHandler> GCCHandler(
new UnknownPragmaHandler(
 
 1101      "#pragma GCC", Callbacks,
 
 1104  std::unique_ptr<UnknownPragmaHandler> ClangHandler(
new UnknownPragmaHandler(
 
 1105      "#pragma clang", Callbacks,
 
 1117  std::unique_ptr<UnknownPragmaHandler> OpenMPHandler(
 
 1118      new UnknownPragmaHandler(
"#pragma omp", Callbacks,
 
 1136    if (
Tok.is(tok::eof) || !
Tok.getLocation().isFileID())
 
 
Defines the Diagnostic-related interfaces.
llvm::MachO::FileType FileType
Defines the clang::MacroInfo and clang::MacroDirective classes.
Defines the PPCallbacks interface.
Defines the clang::Preprocessor interface.
std::pair< const IdentifierInfo *, MacroInfo * > id_macro_pair
static void DoPrintMacros(Preprocessor &PP, raw_ostream *OS)
static void PrintMacroDefinition(const IdentifierInfo &II, const MacroInfo &MI, Preprocessor &PP, raw_ostream *OS)
PrintMacroDefinition - Print a macro definition in a form that will be properly accepted back as a de...
static int MacroIDCompare(const id_macro_pair *LHS, const id_macro_pair *RHS)
static void PrintPreprocessedTokens(Preprocessor &PP, Token &Tok, PrintPPOutputPPCallbacks *Callbacks)
static void outputPrintable(raw_ostream *OS, StringRef Str)
Defines the SourceManager interface.
One of these records is kept for each identifier that is lexed.
tok::PPKeywordKind getPPKeywordID() const
Return the preprocessor keyword ID for this identifier.
StringRef getName() const
Return the actual identifier string.
MacroInfo * getMacroInfo() const
Get the MacroInfo that should be used for this definition.
const MacroInfo * getMacroInfo() const
Encapsulates the data about a macro definition (e.g.
bool isUsed() const
Return false if this macro is defined in the main file and has not yet been used.
bool isFunctionLike() const
const_tokens_iterator tokens_begin() const
param_iterator param_begin() const
bool isBuiltinMacro() const
Return true if this macro requires processing before expansion.
IdentifierInfo *const * param_iterator
Parameters - The list of parameters for a function-like macro.
SourceLocation getDefinitionLoc() const
Return the location that the macro was defined at.
bool tokens_empty() const
param_iterator param_end() const
ArrayRef< Token > tokens() const
bool isGNUVarargs() const
Describes a module or submodule.
std::string getFullModuleName(bool AllowStringLiterals=false) const
Retrieve the full name of this module, including the path from its top-level module.
This interface provides a way to observe the actions of the preprocessor as it does its thing.
PreprocessorOutputOptions - Options for controlling the C preprocessor output (e.g....
unsigned UseLineDirectives
Use #line instead of GCC-style # N.
unsigned ShowMacros
Print macro definitions.
unsigned ShowIncludeDirectives
Print includes, imports etc. within preprocessed output.
unsigned ShowMacroComments
Show comments, even in macros.
unsigned ShowCPP
Print normal preprocessed output.
unsigned MinimizeWhitespace
Ignore whitespace from input.
unsigned KeepSystemIncludes
Do not expand system headers.
unsigned ShowComments
Show comments.
unsigned ShowEmbedDirectives
Print embeds, etc. within preprocessed.
unsigned ShowLineMarkers
Show #line markers.
unsigned DirectivesOnly
Process directives but do not expand macros.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
void IgnorePragmas()
Install empty handlers for all pragmas (making them ignored).
macro_iterator macro_begin(bool IncludeExternalMacros=true) const
void Lex(Token &Result)
Lex the next token for this preprocessor.
void addPPCallbacks(std::unique_ptr< PPCallbacks > C)
void EnterMainSourceFile()
Enter the specified FileID as the main source file, which implicitly adds the builtin defines etc.
macro_iterator macro_end(bool IncludeExternalMacros=true) const
SourceManager & getSourceManager() const
bool getCommentRetentionState() const
void SetMacroExpansionOnlyInDirectives()
Disables macro expansion everywhere except for preprocessor directives.
MacroMap::const_iterator macro_iterator
void LexUnexpandedToken(Token &Result)
Just like Lex, but disables macro expansion of identifier tokens.
void AddPragmaHandler(StringRef Namespace, PragmaHandler *Handler)
Add the specified pragma handler to this preprocessor.
StringRef getSpelling(SourceLocation loc, SmallVectorImpl< char > &buffer, bool *invalid=nullptr) const
Return the 'spelling' of the token at the given location; does not go up to the spelling location or ...
const LangOptions & getLangOpts() const
void LexTokensUntilEOF(std::vector< Token > *Tokens=nullptr)
Lex all tokens for this preprocessor until (and excluding) end of file.
void SetCommentRetentionState(bool KeepComments, bool KeepMacroComments)
Control whether the preprocessor retains comments in output.
void RemovePragmaHandler(StringRef Namespace, PragmaHandler *Handler)
Remove the specific pragma handler from this preprocessor.
Represents an unpacked "presumed" location which can be presented to the user.
const char * getFilename() const
Return the presumed filename of this location.
unsigned getLine() const
Return the presumed line number of this location.
bool isInvalid() const
Return true if this object is invalid or uninitialized.
SourceLocation getIncludeLoc() const
Return the presumed include location of this location.
bool isValid() const
Return true if this is a valid SourceLocation object.
This class handles loading and caching of source files into memory.
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
Token - This structure provides full information about a lexed token.
IdentifierInfo * getIdentifierInfo() const
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
bool hasLeadingSpace() const
Return true if this token has whitespace before it.
bool isNot(tok::TokenKind K) const
bool isAnnotation() const
Return true if this is any of tok::annot_* kind tokens.
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
bool isSystem(CharacteristicKind CK)
Determine whether a file / directory characteristic is for system code.
Severity
Enum values that allow the client to map NOTEs, WARNINGs, and EXTENSIONs to either Ignore (nothing),...
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
The JSON file list parser is used to communicate input to InstallAPI.
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
LLVM_READONLY bool isPrintable(unsigned char c)
Return true if this character is an ASCII printable character; that is, a character that should take ...
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
const FunctionProtoType * T
void DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream *OS, const PreprocessorOutputOptions &Opts)
DoPrintPreprocessedInput - Implement -E mode.
Helper class to shuttle information about embed directives from the preprocessor to the parser throug...
std::optional< PPEmbedParameterIfEmpty > MaybeIfEmptyParam
std::optional< PPEmbedParameterOffset > MaybeOffsetParam
std::optional< PPEmbedParameterLimit > MaybeLimitParam
std::optional< PPEmbedParameterSuffix > MaybeSuffixParam
std::optional< PPEmbedParameterPrefix > MaybePrefixParam