clang  20.0.0git
PrintPreprocessedOutput.cpp
Go to the documentation of this file.
1 //===--- PrintPreprocessedOutput.cpp - Implement the -E mode --------------===//
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 // This code simply runs the preprocessor on the input file and prints out the
10 // result. This is the traditional behavior of the -E option.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "clang/Basic/CharInfo.h"
15 #include "clang/Basic/Diagnostic.h"
18 #include "clang/Frontend/Utils.h"
19 #include "clang/Lex/MacroInfo.h"
20 #include "clang/Lex/PPCallbacks.h"
21 #include "clang/Lex/Pragma.h"
22 #include "clang/Lex/Preprocessor.h"
25 #include "llvm/ADT/STLExtras.h"
26 #include "llvm/ADT/SmallString.h"
27 #include "llvm/ADT/StringRef.h"
28 #include "llvm/Support/ErrorHandling.h"
29 #include "llvm/Support/raw_ostream.h"
30 #include <cstdio>
31 using namespace clang;
32 
33 /// PrintMacroDefinition - Print a macro definition in a form that will be
34 /// properly accepted back as a definition.
35 static void PrintMacroDefinition(const IdentifierInfo &II, const MacroInfo &MI,
36  Preprocessor &PP, raw_ostream *OS) {
37  *OS << "#define " << II.getName();
38 
39  if (MI.isFunctionLike()) {
40  *OS << '(';
41  if (!MI.param_empty()) {
43  for (; AI+1 != E; ++AI) {
44  *OS << (*AI)->getName();
45  *OS << ',';
46  }
47 
48  // Last argument.
49  if ((*AI)->getName() == "__VA_ARGS__")
50  *OS << "...";
51  else
52  *OS << (*AI)->getName();
53  }
54 
55  if (MI.isGNUVarargs())
56  *OS << "..."; // #define foo(x...)
57 
58  *OS << ')';
59  }
60 
61  // GCC always emits a space, even if the macro body is empty. However, do not
62  // want to emit two spaces if the first token has a leading space.
63  if (MI.tokens_empty() || !MI.tokens_begin()->hasLeadingSpace())
64  *OS << ' ';
65 
66  SmallString<128> SpellingBuffer;
67  for (const auto &T : MI.tokens()) {
68  if (T.hasLeadingSpace())
69  *OS << ' ';
70 
71  *OS << PP.getSpelling(T, SpellingBuffer);
72  }
73 }
74 
75 //===----------------------------------------------------------------------===//
76 // Preprocessed token printer
77 //===----------------------------------------------------------------------===//
78 
79 namespace {
80 class PrintPPOutputPPCallbacks : public PPCallbacks {
81  Preprocessor &PP;
83  TokenConcatenation ConcatInfo;
84 public:
85  raw_ostream *OS;
86 private:
87  unsigned CurLine;
88 
89  bool EmittedTokensOnThisLine;
90  bool EmittedDirectiveOnThisLine;
92  SmallString<512> CurFilename;
93  bool Initialized;
94  bool DisableLineMarkers;
95  bool DumpDefines;
96  bool DumpIncludeDirectives;
97  bool DumpEmbedDirectives;
98  bool UseLineDirectives;
99  bool IsFirstFileEntered;
100  bool MinimizeWhitespace;
101  bool DirectivesOnly;
102  bool KeepSystemIncludes;
103  raw_ostream *OrigOS;
104  std::unique_ptr<llvm::raw_null_ostream> NullOS;
105  unsigned NumToksToSkip;
106 
107  Token PrevTok;
108  Token PrevPrevTok;
109 
110 public:
111  PrintPPOutputPPCallbacks(Preprocessor &pp, raw_ostream *os, bool lineMarkers,
112  bool defines, bool DumpIncludeDirectives,
113  bool DumpEmbedDirectives, bool UseLineDirectives,
114  bool MinimizeWhitespace, bool DirectivesOnly,
115  bool KeepSystemIncludes)
116  : PP(pp), SM(PP.getSourceManager()), ConcatInfo(PP), OS(os),
117  DisableLineMarkers(lineMarkers), DumpDefines(defines),
118  DumpIncludeDirectives(DumpIncludeDirectives),
119  DumpEmbedDirectives(DumpEmbedDirectives),
120  UseLineDirectives(UseLineDirectives),
121  MinimizeWhitespace(MinimizeWhitespace), DirectivesOnly(DirectivesOnly),
122  KeepSystemIncludes(KeepSystemIncludes), OrigOS(os), NumToksToSkip(0) {
123  CurLine = 0;
124  CurFilename += "<uninit>";
125  EmittedTokensOnThisLine = false;
126  EmittedDirectiveOnThisLine = false;
128  Initialized = false;
129  IsFirstFileEntered = false;
130  if (KeepSystemIncludes)
131  NullOS = std::make_unique<llvm::raw_null_ostream>();
132 
133  PrevTok.startToken();
134  PrevPrevTok.startToken();
135  }
136 
137  /// Returns true if #embed directives should be expanded into a comma-
138  /// delimited list of integer constants or not.
139  bool expandEmbedContents() const { return !DumpEmbedDirectives; }
140 
141  bool isMinimizeWhitespace() const { return MinimizeWhitespace; }
142 
143  void setEmittedTokensOnThisLine() { EmittedTokensOnThisLine = true; }
144  bool hasEmittedTokensOnThisLine() const { return EmittedTokensOnThisLine; }
145 
146  void setEmittedDirectiveOnThisLine() { EmittedDirectiveOnThisLine = true; }
147  bool hasEmittedDirectiveOnThisLine() const {
148  return EmittedDirectiveOnThisLine;
149  }
150 
151  /// Ensure that the output stream position is at the beginning of a new line
152  /// and inserts one if it does not. It is intended to ensure that directives
153  /// inserted by the directives not from the input source (such as #line) are
154  /// in the first column. To insert newlines that represent the input, use
155  /// MoveToLine(/*...*/, /*RequireStartOfLine=*/true).
156  void startNewLineIfNeeded();
157 
158  void FileChanged(SourceLocation Loc, FileChangeReason Reason,
160  FileID PrevFID) override;
161  void EmbedDirective(SourceLocation HashLoc, StringRef FileName, bool IsAngled,
163  const LexEmbedParametersResult &Params) override;
164  void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
165  StringRef FileName, bool IsAngled,
166  CharSourceRange FilenameRange,
167  OptionalFileEntryRef File, StringRef SearchPath,
168  StringRef RelativePath, const Module *SuggestedModule,
169  bool ModuleImported,
171  void Ident(SourceLocation Loc, StringRef str) override;
172  void PragmaMessage(SourceLocation Loc, StringRef Namespace,
173  PragmaMessageKind Kind, StringRef Str) override;
174  void PragmaDebug(SourceLocation Loc, StringRef DebugType) override;
175  void PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace) override;
176  void PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace) override;
177  void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
178  diag::Severity Map, StringRef Str) override;
179  void PragmaWarning(SourceLocation Loc, PragmaWarningSpecifier WarningSpec,
180  ArrayRef<int> Ids) override;
181  void PragmaWarningPush(SourceLocation Loc, int Level) override;
182  void PragmaWarningPop(SourceLocation Loc) override;
183  void PragmaExecCharsetPush(SourceLocation Loc, StringRef Str) override;
184  void PragmaExecCharsetPop(SourceLocation Loc) override;
185  void PragmaAssumeNonNullBegin(SourceLocation Loc) override;
186  void PragmaAssumeNonNullEnd(SourceLocation Loc) override;
187 
188  /// Insert whitespace before emitting the next token.
189  ///
190  /// @param Tok Next token to be emitted.
191  /// @param RequireSpace Ensure at least one whitespace is emitted. Useful
192  /// if non-tokens have been emitted to the stream.
193  /// @param RequireSameLine Never emit newlines. Useful when semantics depend
194  /// on being on the same line, such as directives.
195  void HandleWhitespaceBeforeTok(const Token &Tok, bool RequireSpace,
196  bool RequireSameLine);
197 
198  /// Move to the line of the provided source location. This will
199  /// return true if a newline was inserted or if
200  /// the requested location is the first token on the first line.
201  /// In these cases the next output will be the first column on the line and
202  /// make it possible to insert indention. The newline was inserted
203  /// implicitly when at the beginning of the file.
204  ///
205  /// @param Tok Token where to move to.
206  /// @param RequireStartOfLine Whether the next line depends on being in the
207  /// first column, such as a directive.
208  ///
209  /// @return Whether column adjustments are necessary.
210  bool MoveToLine(const Token &Tok, bool RequireStartOfLine) {
211  PresumedLoc PLoc = SM.getPresumedLoc(Tok.getLocation());
212  unsigned TargetLine = PLoc.isValid() ? PLoc.getLine() : CurLine;
213  bool IsFirstInFile =
214  Tok.isAtStartOfLine() && PLoc.isValid() && PLoc.getLine() == 1;
215  return MoveToLine(TargetLine, RequireStartOfLine) || IsFirstInFile;
216  }
217 
218  /// Move to the line of the provided source location. Returns true if a new
219  /// line was inserted.
220  bool MoveToLine(SourceLocation Loc, bool RequireStartOfLine) {
221  PresumedLoc PLoc = SM.getPresumedLoc(Loc);
222  unsigned TargetLine = PLoc.isValid() ? PLoc.getLine() : CurLine;
223  return MoveToLine(TargetLine, RequireStartOfLine);
224  }
225  bool MoveToLine(unsigned LineNo, bool RequireStartOfLine);
226 
227  bool AvoidConcat(const Token &PrevPrevTok, const Token &PrevTok,
228  const Token &Tok) {
229  return ConcatInfo.AvoidConcat(PrevPrevTok, PrevTok, Tok);
230  }
231  void WriteFooterInfo(StringRef Footer);
232  void WriteFooterContent(StringRef CodeFooter);
233  void WriteLineInfo(unsigned LineNo, const char *Extra=nullptr,
234  unsigned ExtraLen=0);
235  bool LineMarkersAreDisabled() const { return DisableLineMarkers; }
236  void HandleNewlinesInToken(const char *TokStr, unsigned Len);
237 
238  /// MacroDefined - This hook is called whenever a macro definition is seen.
239  void MacroDefined(const Token &MacroNameTok,
240  const MacroDirective *MD) override;
241 
242  /// MacroUndefined - This hook is called whenever a macro #undef is seen.
243  void MacroUndefined(const Token &MacroNameTok,
244  const MacroDefinition &MD,
245  const MacroDirective *Undef) override;
246 
247  void BeginModule(const Module *M);
248  void EndModule(const Module *M);
249 
250  unsigned GetNumToksToSkip() const { return NumToksToSkip; }
251  void ResetSkipToks() { NumToksToSkip = 0; }
252 };
253 } // end anonymous namespace
254 
255 void PrintPPOutputPPCallbacks::WriteFooterInfo(StringRef Footer) {
256  *OS << '#' << ' ' << 1 << ' ' << '"';
257  *OS << "<built-in>" << '"' << ' ' << "1";
258  *OS << '\n';
259  *OS << Twine("# 1 ") + "\"" + Footer + "\"" + Twine(" 1");
260  *OS << '\n';
261 }
262 
263 void PrintPPOutputPPCallbacks::WriteFooterContent(StringRef CodeFooter) {
264  *OS << CodeFooter;
265  *OS << '\n';
266 }
267 
268 void PrintPPOutputPPCallbacks::WriteLineInfo(unsigned LineNo,
269  const char *Extra,
270  unsigned ExtraLen) {
271  startNewLineIfNeeded();
272 
273  // Emit #line directives or GNU line markers depending on what mode we're in.
274  if (UseLineDirectives) {
275  *OS << "#line" << ' ' << LineNo << ' ' << '"';
276  OS->write_escaped(CurFilename);
277  *OS << '"';
278  } else {
279  *OS << '#' << ' ' << LineNo << ' ' << '"';
280  OS->write_escaped(CurFilename);
281  *OS << '"';
282 
283  if (ExtraLen)
284  OS->write(Extra, ExtraLen);
285 
286  if (FileType == SrcMgr::C_System)
287  OS->write(" 3", 2);
288  else if (FileType == SrcMgr::C_ExternCSystem)
289  OS->write(" 3 4", 4);
290  }
291  *OS << '\n';
292 }
293 
294 /// MoveToLine - Move the output to the source line specified by the location
295 /// object. We can do this by emitting some number of \n's, or be emitting a
296 /// #line directive. This returns false if already at the specified line, true
297 /// if some newlines were emitted.
298 bool PrintPPOutputPPCallbacks::MoveToLine(unsigned LineNo,
299  bool RequireStartOfLine) {
300  // If it is required to start a new line or finish the current, insert
301  // vertical whitespace now and take it into account when moving to the
302  // expected line.
303  bool StartedNewLine = false;
304  if ((RequireStartOfLine && EmittedTokensOnThisLine) ||
305  EmittedDirectiveOnThisLine) {
306  *OS << '\n';
307  StartedNewLine = true;
308  CurLine += 1;
309  EmittedTokensOnThisLine = false;
310  EmittedDirectiveOnThisLine = false;
311  }
312 
313  // If this line is "close enough" to the original line, just print newlines,
314  // otherwise print a #line directive.
315  if (CurLine == LineNo) {
316  // Nothing to do if we are already on the correct line.
317  } else if (MinimizeWhitespace && DisableLineMarkers) {
318  // With -E -P -fminimize-whitespace, don't emit anything if not necessary.
319  } else if (!StartedNewLine && LineNo - CurLine == 1) {
320  // Printing a single line has priority over printing a #line directive, even
321  // when minimizing whitespace which otherwise would print #line directives
322  // for every single line.
323  *OS << '\n';
324  StartedNewLine = true;
325  } else if (!DisableLineMarkers) {
326  if (LineNo - CurLine <= 8) {
327  const char *NewLines = "\n\n\n\n\n\n\n\n";
328  OS->write(NewLines, LineNo - CurLine);
329  } else {
330  // Emit a #line or line marker.
331  WriteLineInfo(LineNo, nullptr, 0);
332  }
333  StartedNewLine = true;
334  } else if (EmittedTokensOnThisLine) {
335  // If we are not on the correct line and don't need to be line-correct,
336  // at least ensure we start on a new line.
337  *OS << '\n';
338  StartedNewLine = true;
339  }
340 
341  if (StartedNewLine) {
342  EmittedTokensOnThisLine = false;
343  EmittedDirectiveOnThisLine = false;
344  }
345 
346  CurLine = LineNo;
347  return StartedNewLine;
348 }
349 
350 void PrintPPOutputPPCallbacks::startNewLineIfNeeded() {
351  if (EmittedTokensOnThisLine || EmittedDirectiveOnThisLine) {
352  *OS << '\n';
353  EmittedTokensOnThisLine = false;
354  EmittedDirectiveOnThisLine = false;
355  }
356 }
357 
358 /// FileChanged - Whenever the preprocessor enters or exits a #include file
359 /// it invokes this handler. Update our conception of the current source
360 /// position.
361 void PrintPPOutputPPCallbacks::FileChanged(SourceLocation Loc,
362  FileChangeReason Reason,
363  SrcMgr::CharacteristicKind NewFileType,
364  FileID PrevFID) {
365  // Unless we are exiting a #include, make sure to skip ahead to the line the
366  // #include directive was at.
367  SourceManager &SourceMgr = SM;
368 
369  PresumedLoc UserLoc = SourceMgr.getPresumedLoc(Loc);
370  if (UserLoc.isInvalid())
371  return;
372 
373  unsigned NewLine = UserLoc.getLine();
374 
375  if (Reason == PPCallbacks::EnterFile) {
376  SourceLocation IncludeLoc = UserLoc.getIncludeLoc();
377  if (IncludeLoc.isValid())
378  MoveToLine(IncludeLoc, /*RequireStartOfLine=*/false);
379  } else if (Reason == PPCallbacks::SystemHeaderPragma) {
380  // GCC emits the # directive for this directive on the line AFTER the
381  // directive and emits a bunch of spaces that aren't needed. This is because
382  // otherwise we will emit a line marker for THIS line, which requires an
383  // extra blank line after the directive to avoid making all following lines
384  // off by one. We can do better by simply incrementing NewLine here.
385  NewLine += 1;
386  }
387 
388  CurLine = NewLine;
389 
390  // In KeepSystemIncludes mode, redirect OS as needed.
391  if (KeepSystemIncludes && (isSystem(FileType) != isSystem(NewFileType)))
392  OS = isSystem(FileType) ? OrigOS : NullOS.get();
393 
394  CurFilename.clear();
395  CurFilename += UserLoc.getFilename();
396  FileType = NewFileType;
397 
398  if (DisableLineMarkers) {
399  if (!MinimizeWhitespace)
400  startNewLineIfNeeded();
401  return;
402  }
403 
404  if (!Initialized) {
405  WriteLineInfo(CurLine);
406  Initialized = true;
407  }
408 
409  // Do not emit an enter marker for the main file (which we expect is the first
410  // entered file). This matches gcc, and improves compatibility with some tools
411  // which track the # line markers as a way to determine when the preprocessed
412  // output is in the context of the main file.
413  if (Reason == PPCallbacks::EnterFile && !IsFirstFileEntered) {
414  IsFirstFileEntered = true;
415  return;
416  }
417 
418  switch (Reason) {
420  WriteLineInfo(CurLine, " 1", 2);
421  break;
423  WriteLineInfo(CurLine, " 2", 2);
424  break;
427  WriteLineInfo(CurLine);
428  break;
429  }
430 }
431 
432 void PrintPPOutputPPCallbacks::EmbedDirective(
433  SourceLocation HashLoc, StringRef FileName, bool IsAngled,
434  OptionalFileEntryRef File, const LexEmbedParametersResult &Params) {
435  if (!DumpEmbedDirectives)
436  return;
437 
438  // The EmbedDirective() callback is called before we produce the annotation
439  // token stream for the directive. We skip printing the annotation tokens
440  // within PrintPreprocessedTokens(), but we also need to skip the prefix,
441  // suffix, and if_empty tokens as those are inserted directly into the token
442  // stream and would otherwise be printed immediately after printing the
443  // #embed directive.
444  //
445  // FIXME: counting tokens to skip is a kludge but we have no way to know
446  // which tokens were inserted as part of the embed and which ones were
447  // explicitly written by the user.
448  MoveToLine(HashLoc, /*RequireStartOfLine=*/true);
449  *OS << "#embed " << (IsAngled ? '<' : '"') << FileName
450  << (IsAngled ? '>' : '"');
451 
452  auto PrintToks = [&](llvm::ArrayRef<Token> Toks) {
453  SmallString<128> SpellingBuffer;
454  for (const Token &T : Toks) {
455  if (T.hasLeadingSpace())
456  *OS << " ";
457  *OS << PP.getSpelling(T, SpellingBuffer);
458  }
459  };
460  bool SkipAnnotToks = true;
461  if (Params.MaybeIfEmptyParam) {
462  *OS << " if_empty(";
463  PrintToks(Params.MaybeIfEmptyParam->Tokens);
464  *OS << ")";
465  // If the file is empty, we can skip those tokens. If the file is not
466  // empty, we skip the annotation tokens.
467  if (File && !File->getSize()) {
468  NumToksToSkip += Params.MaybeIfEmptyParam->Tokens.size();
469  SkipAnnotToks = false;
470  }
471  }
472 
473  if (Params.MaybeLimitParam) {
474  *OS << " limit(" << Params.MaybeLimitParam->Limit << ")";
475  }
476  if (Params.MaybeOffsetParam) {
477  *OS << " clang::offset(" << Params.MaybeOffsetParam->Offset << ")";
478  }
479  if (Params.MaybePrefixParam) {
480  *OS << " prefix(";
481  PrintToks(Params.MaybePrefixParam->Tokens);
482  *OS << ")";
483  NumToksToSkip += Params.MaybePrefixParam->Tokens.size();
484  }
485  if (Params.MaybeSuffixParam) {
486  *OS << " suffix(";
487  PrintToks(Params.MaybeSuffixParam->Tokens);
488  *OS << ")";
489  NumToksToSkip += Params.MaybeSuffixParam->Tokens.size();
490  }
491 
492  // We may need to skip the annotation token.
493  if (SkipAnnotToks)
494  NumToksToSkip++;
495 
496  *OS << " /* clang -E -dE */";
497  setEmittedDirectiveOnThisLine();
498 }
499 
500 void PrintPPOutputPPCallbacks::InclusionDirective(
501  SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName,
502  bool IsAngled, CharSourceRange FilenameRange, OptionalFileEntryRef File,
503  StringRef SearchPath, StringRef RelativePath, const Module *SuggestedModule,
504  bool ModuleImported, SrcMgr::CharacteristicKind FileType) {
505  // In -dI mode, dump #include directives prior to dumping their content or
506  // interpretation. Similar for -fkeep-system-includes.
507  if (DumpIncludeDirectives || (KeepSystemIncludes && isSystem(FileType))) {
508  MoveToLine(HashLoc, /*RequireStartOfLine=*/true);
509  const std::string TokenText = PP.getSpelling(IncludeTok);
510  assert(!TokenText.empty());
511  *OS << "#" << TokenText << " "
512  << (IsAngled ? '<' : '"') << FileName << (IsAngled ? '>' : '"')
513  << " /* clang -E "
514  << (DumpIncludeDirectives ? "-dI" : "-fkeep-system-includes")
515  << " */";
516  setEmittedDirectiveOnThisLine();
517  }
518 
519  // When preprocessing, turn implicit imports into module import pragmas.
520  if (ModuleImported) {
521  switch (IncludeTok.getIdentifierInfo()->getPPKeywordID()) {
522  case tok::pp_include:
523  case tok::pp_import:
525  MoveToLine(HashLoc, /*RequireStartOfLine=*/true);
526  *OS << "#pragma clang module import "
527  << SuggestedModule->getFullModuleName(true)
528  << " /* clang -E: implicit import for "
529  << "#" << PP.getSpelling(IncludeTok) << " "
530  << (IsAngled ? '<' : '"') << FileName << (IsAngled ? '>' : '"')
531  << " */";
532  setEmittedDirectiveOnThisLine();
533  break;
534 
536  // #__include_macros has no effect on a user of a preprocessed source
537  // file; the only effect is on preprocessing.
538  //
539  // FIXME: That's not *quite* true: it causes the module in question to
540  // be loaded, which can affect downstream diagnostics.
541  break;
542 
543  default:
544  llvm_unreachable("unknown include directive kind");
545  break;
546  }
547  }
548 }
549 
550 /// Handle entering the scope of a module during a module compilation.
551 void PrintPPOutputPPCallbacks::BeginModule(const Module *M) {
552  startNewLineIfNeeded();
553  *OS << "#pragma clang module begin " << M->getFullModuleName(true);
554  setEmittedDirectiveOnThisLine();
555 }
556 
557 /// Handle leaving the scope of a module during a module compilation.
558 void PrintPPOutputPPCallbacks::EndModule(const Module *M) {
559  startNewLineIfNeeded();
560  *OS << "#pragma clang module end /*" << M->getFullModuleName(true) << "*/";
561  setEmittedDirectiveOnThisLine();
562 }
563 
564 /// Ident - Handle #ident directives when read by the preprocessor.
565 ///
566 void PrintPPOutputPPCallbacks::Ident(SourceLocation Loc, StringRef S) {
567  MoveToLine(Loc, /*RequireStartOfLine=*/true);
568 
569  OS->write("#ident ", strlen("#ident "));
570  OS->write(S.begin(), S.size());
571  setEmittedTokensOnThisLine();
572 }
573 
574 /// MacroDefined - This hook is called whenever a macro definition is seen.
575 void PrintPPOutputPPCallbacks::MacroDefined(const Token &MacroNameTok,
576  const MacroDirective *MD) {
577  const MacroInfo *MI = MD->getMacroInfo();
578  // Print out macro definitions in -dD mode and when we have -fdirectives-only
579  // for C++20 header units.
580  if ((!DumpDefines && !DirectivesOnly) ||
581  // Ignore __FILE__ etc.
582  MI->isBuiltinMacro())
583  return;
584 
585  SourceLocation DefLoc = MI->getDefinitionLoc();
586  if (DirectivesOnly && !MI->isUsed()) {
588  if (SM.isWrittenInBuiltinFile(DefLoc) ||
589  SM.isWrittenInCommandLineFile(DefLoc))
590  return;
591  }
592  MoveToLine(DefLoc, /*RequireStartOfLine=*/true);
593  PrintMacroDefinition(*MacroNameTok.getIdentifierInfo(), *MI, PP, OS);
594  setEmittedDirectiveOnThisLine();
595 }
596 
597 void PrintPPOutputPPCallbacks::MacroUndefined(const Token &MacroNameTok,
598  const MacroDefinition &MD,
599  const MacroDirective *Undef) {
600  // Print out macro definitions in -dD mode and when we have -fdirectives-only
601  // for C++20 header units.
602  if (!DumpDefines && !DirectivesOnly)
603  return;
604 
605  MoveToLine(MacroNameTok.getLocation(), /*RequireStartOfLine=*/true);
606  *OS << "#undef " << MacroNameTok.getIdentifierInfo()->getName();
607  setEmittedDirectiveOnThisLine();
608 }
609 
610 static void outputPrintable(raw_ostream *OS, StringRef Str) {
611  for (unsigned char Char : Str) {
612  if (isPrintable(Char) && Char != '\\' && Char != '"')
613  *OS << (char)Char;
614  else // Output anything hard as an octal escape.
615  *OS << '\\'
616  << (char)('0' + ((Char >> 6) & 7))
617  << (char)('0' + ((Char >> 3) & 7))
618  << (char)('0' + ((Char >> 0) & 7));
619  }
620 }
621 
622 void PrintPPOutputPPCallbacks::PragmaMessage(SourceLocation Loc,
623  StringRef Namespace,
624  PragmaMessageKind Kind,
625  StringRef Str) {
626  MoveToLine(Loc, /*RequireStartOfLine=*/true);
627  *OS << "#pragma ";
628  if (!Namespace.empty())
629  *OS << Namespace << ' ';
630  switch (Kind) {
631  case PMK_Message:
632  *OS << "message(\"";
633  break;
634  case PMK_Warning:
635  *OS << "warning \"";
636  break;
637  case PMK_Error:
638  *OS << "error \"";
639  break;
640  }
641 
642  outputPrintable(OS, Str);
643  *OS << '"';
644  if (Kind == PMK_Message)
645  *OS << ')';
646  setEmittedDirectiveOnThisLine();
647 }
648 
649 void PrintPPOutputPPCallbacks::PragmaDebug(SourceLocation Loc,
650  StringRef DebugType) {
651  MoveToLine(Loc, /*RequireStartOfLine=*/true);
652 
653  *OS << "#pragma clang __debug ";
654  *OS << DebugType;
655 
656  setEmittedDirectiveOnThisLine();
657 }
658 
659 void PrintPPOutputPPCallbacks::
660 PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace) {
661  MoveToLine(Loc, /*RequireStartOfLine=*/true);
662  *OS << "#pragma " << Namespace << " diagnostic push";
663  setEmittedDirectiveOnThisLine();
664 }
665 
666 void PrintPPOutputPPCallbacks::
667 PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace) {
668  MoveToLine(Loc, /*RequireStartOfLine=*/true);
669  *OS << "#pragma " << Namespace << " diagnostic pop";
670  setEmittedDirectiveOnThisLine();
671 }
672 
673 void PrintPPOutputPPCallbacks::PragmaDiagnostic(SourceLocation Loc,
674  StringRef Namespace,
675  diag::Severity Map,
676  StringRef Str) {
677  MoveToLine(Loc, /*RequireStartOfLine=*/true);
678  *OS << "#pragma " << Namespace << " diagnostic ";
679  switch (Map) {
681  *OS << "remark";
682  break;
684  *OS << "warning";
685  break;
687  *OS << "error";
688  break;
690  *OS << "ignored";
691  break;
693  *OS << "fatal";
694  break;
695  }
696  *OS << " \"" << Str << '"';
697  setEmittedDirectiveOnThisLine();
698 }
699 
700 void PrintPPOutputPPCallbacks::PragmaWarning(SourceLocation Loc,
701  PragmaWarningSpecifier WarningSpec,
702  ArrayRef<int> Ids) {
703  MoveToLine(Loc, /*RequireStartOfLine=*/true);
704 
705  *OS << "#pragma warning(";
706  switch(WarningSpec) {
707  case PWS_Default: *OS << "default"; break;
708  case PWS_Disable: *OS << "disable"; break;
709  case PWS_Error: *OS << "error"; break;
710  case PWS_Once: *OS << "once"; break;
711  case PWS_Suppress: *OS << "suppress"; break;
712  case PWS_Level1: *OS << '1'; break;
713  case PWS_Level2: *OS << '2'; break;
714  case PWS_Level3: *OS << '3'; break;
715  case PWS_Level4: *OS << '4'; break;
716  }
717  *OS << ':';
718 
719  for (ArrayRef<int>::iterator I = Ids.begin(), E = Ids.end(); I != E; ++I)
720  *OS << ' ' << *I;
721  *OS << ')';
722  setEmittedDirectiveOnThisLine();
723 }
724 
725 void PrintPPOutputPPCallbacks::PragmaWarningPush(SourceLocation Loc,
726  int Level) {
727  MoveToLine(Loc, /*RequireStartOfLine=*/true);
728  *OS << "#pragma warning(push";
729  if (Level >= 0)
730  *OS << ", " << Level;
731  *OS << ')';
732  setEmittedDirectiveOnThisLine();
733 }
734 
735 void PrintPPOutputPPCallbacks::PragmaWarningPop(SourceLocation Loc) {
736  MoveToLine(Loc, /*RequireStartOfLine=*/true);
737  *OS << "#pragma warning(pop)";
738  setEmittedDirectiveOnThisLine();
739 }
740 
741 void PrintPPOutputPPCallbacks::PragmaExecCharsetPush(SourceLocation Loc,
742  StringRef Str) {
743  MoveToLine(Loc, /*RequireStartOfLine=*/true);
744  *OS << "#pragma character_execution_set(push";
745  if (!Str.empty())
746  *OS << ", " << Str;
747  *OS << ')';
748  setEmittedDirectiveOnThisLine();
749 }
750 
751 void PrintPPOutputPPCallbacks::PragmaExecCharsetPop(SourceLocation Loc) {
752  MoveToLine(Loc, /*RequireStartOfLine=*/true);
753  *OS << "#pragma character_execution_set(pop)";
754  setEmittedDirectiveOnThisLine();
755 }
756 
757 void PrintPPOutputPPCallbacks::
758 PragmaAssumeNonNullBegin(SourceLocation Loc) {
759  MoveToLine(Loc, /*RequireStartOfLine=*/true);
760  *OS << "#pragma clang assume_nonnull begin";
761  setEmittedDirectiveOnThisLine();
762 }
763 
764 void PrintPPOutputPPCallbacks::
765 PragmaAssumeNonNullEnd(SourceLocation Loc) {
766  MoveToLine(Loc, /*RequireStartOfLine=*/true);
767  *OS << "#pragma clang assume_nonnull end";
768  setEmittedDirectiveOnThisLine();
769 }
770 
771 void PrintPPOutputPPCallbacks::HandleWhitespaceBeforeTok(const Token &Tok,
772  bool RequireSpace,
773  bool RequireSameLine) {
774  // These tokens are not expanded to anything and don't need whitespace before
775  // them.
776  if (Tok.is(tok::eof) ||
777  (Tok.isAnnotation() && !Tok.is(tok::annot_header_unit) &&
778  !Tok.is(tok::annot_module_begin) && !Tok.is(tok::annot_module_end) &&
779  !Tok.is(tok::annot_repl_input_end) && !Tok.is(tok::annot_embed)))
780  return;
781 
782  // EmittedDirectiveOnThisLine takes priority over RequireSameLine.
783  if ((!RequireSameLine || EmittedDirectiveOnThisLine) &&
784  MoveToLine(Tok, /*RequireStartOfLine=*/EmittedDirectiveOnThisLine)) {
785  if (MinimizeWhitespace) {
786  // Avoid interpreting hash as a directive under -fpreprocessed.
787  if (Tok.is(tok::hash))
788  *OS << ' ';
789  } else {
790  // Print out space characters so that the first token on a line is
791  // indented for easy reading.
792  unsigned ColNo = SM.getExpansionColumnNumber(Tok.getLocation());
793 
794  // The first token on a line can have a column number of 1, yet still
795  // expect leading white space, if a macro expansion in column 1 starts
796  // with an empty macro argument, or an empty nested macro expansion. In
797  // this case, move the token to column 2.
798  if (ColNo == 1 && Tok.hasLeadingSpace())
799  ColNo = 2;
800 
801  // This hack prevents stuff like:
802  // #define HASH #
803  // HASH define foo bar
804  // From having the # character end up at column 1, which makes it so it
805  // is not handled as a #define next time through the preprocessor if in
806  // -fpreprocessed mode.
807  if (ColNo <= 1 && Tok.is(tok::hash))
808  *OS << ' ';
809 
810  // Otherwise, indent the appropriate number of spaces.
811  for (; ColNo > 1; --ColNo)
812  *OS << ' ';
813  }
814  } else {
815  // Insert whitespace between the previous and next token if either
816  // - The caller requires it
817  // - The input had whitespace between them and we are not in
818  // whitespace-minimization mode
819  // - The whitespace is necessary to keep the tokens apart and there is not
820  // already a newline between them
821  if (RequireSpace || (!MinimizeWhitespace && Tok.hasLeadingSpace()) ||
822  ((EmittedTokensOnThisLine || EmittedDirectiveOnThisLine) &&
823  AvoidConcat(PrevPrevTok, PrevTok, Tok)))
824  *OS << ' ';
825  }
826 
827  PrevPrevTok = PrevTok;
828  PrevTok = Tok;
829 }
830 
831 void PrintPPOutputPPCallbacks::HandleNewlinesInToken(const char *TokStr,
832  unsigned Len) {
833  unsigned NumNewlines = 0;
834  for (; Len; --Len, ++TokStr) {
835  if (*TokStr != '\n' &&
836  *TokStr != '\r')
837  continue;
838 
839  ++NumNewlines;
840 
841  // If we have \n\r or \r\n, skip both and count as one line.
842  if (Len != 1 &&
843  (TokStr[1] == '\n' || TokStr[1] == '\r') &&
844  TokStr[0] != TokStr[1]) {
845  ++TokStr;
846  --Len;
847  }
848  }
849 
850  if (NumNewlines == 0) return;
851 
852  CurLine += NumNewlines;
853 }
854 
855 
856 namespace {
857 struct UnknownPragmaHandler : public PragmaHandler {
858  const char *Prefix;
859  PrintPPOutputPPCallbacks *Callbacks;
860 
861  // Set to true if tokens should be expanded
862  bool ShouldExpandTokens;
863 
864  UnknownPragmaHandler(const char *prefix, PrintPPOutputPPCallbacks *callbacks,
865  bool RequireTokenExpansion)
866  : Prefix(prefix), Callbacks(callbacks),
867  ShouldExpandTokens(RequireTokenExpansion) {}
868  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
869  Token &PragmaTok) override {
870  // Figure out what line we went to and insert the appropriate number of
871  // newline characters.
872  Callbacks->MoveToLine(PragmaTok.getLocation(), /*RequireStartOfLine=*/true);
873  Callbacks->OS->write(Prefix, strlen(Prefix));
874  Callbacks->setEmittedTokensOnThisLine();
875 
876  if (ShouldExpandTokens) {
877  // The first token does not have expanded macros. Expand them, if
878  // required.
879  auto Toks = std::make_unique<Token[]>(1);
880  Toks[0] = PragmaTok;
881  PP.EnterTokenStream(std::move(Toks), /*NumToks=*/1,
882  /*DisableMacroExpansion=*/false,
883  /*IsReinject=*/false);
884  PP.Lex(PragmaTok);
885  }
886 
887  // Read and print all of the pragma tokens.
888  bool IsFirst = true;
889  while (PragmaTok.isNot(tok::eod)) {
890  Callbacks->HandleWhitespaceBeforeTok(PragmaTok, /*RequireSpace=*/IsFirst,
891  /*RequireSameLine=*/true);
892  IsFirst = false;
893  std::string TokSpell = PP.getSpelling(PragmaTok);
894  Callbacks->OS->write(&TokSpell[0], TokSpell.size());
895  Callbacks->setEmittedTokensOnThisLine();
896 
897  if (ShouldExpandTokens)
898  PP.Lex(PragmaTok);
899  else
900  PP.LexUnexpandedToken(PragmaTok);
901  }
902  Callbacks->setEmittedDirectiveOnThisLine();
903  }
904 };
905 } // end anonymous namespace
906 
908  std::string Footer,
909  PrintPPOutputPPCallbacks *Callbacks) {
910  SourceManager &SourceMgr = PP.getSourceManager();
911  PresumedLoc UserLoc = SourceMgr.getPresumedLoc(Loc);
912  if (UserLoc.isInvalid())
913  return;
914  FileID FooterFileID = SourceMgr.ComputeValidFooterFileID(Footer);
915  StringRef FooterContentBuffer = SourceMgr.getBufferData(FooterFileID);
916  // print out the name of the integration footer.
917  Callbacks->WriteFooterInfo(Footer);
918  SmallVector<StringRef, 8> FooterContentArr;
919  FooterContentBuffer.split(FooterContentArr, '\r');
920  // print out the content of the integration footer.
921  for (auto &Val : FooterContentArr) {
922  Val.consume_front("\n");
923  if (!Val.empty())
924  Callbacks->WriteFooterContent(Val);
925  }
926 }
927 
929  PrintPPOutputPPCallbacks *Callbacks) {
930  bool DropComments = PP.getLangOpts().TraditionalCPP &&
932 
933  bool IsStartOfLine = false;
934  char Buffer[256];
935  while (true) {
936  // Two lines joined with line continuation ('\' as last character on the
937  // line) must be emitted as one line even though Tok.getLine() returns two
938  // different values. In this situation Tok.isAtStartOfLine() is false even
939  // though it may be the first token on the lexical line. When
940  // dropping/skipping a token that is at the start of a line, propagate the
941  // start-of-line-ness to the next token to not append it to the previous
942  // line.
943  IsStartOfLine = IsStartOfLine || Tok.isAtStartOfLine();
944 
945  Callbacks->HandleWhitespaceBeforeTok(Tok, /*RequireSpace=*/false,
946  /*RequireSameLine=*/!IsStartOfLine);
947 
948  if (DropComments && Tok.is(tok::comment)) {
949  // Skip comments. Normally the preprocessor does not generate
950  // tok::comment nodes at all when not keeping comments, but under
951  // -traditional-cpp the lexer keeps /all/ whitespace, including comments.
952  PP.Lex(Tok);
953  continue;
954  } else if (Tok.is(tok::annot_repl_input_end)) {
955  PP.Lex(Tok);
956  continue;
957  } else if (Tok.is(tok::eod)) {
958  // Don't print end of directive tokens, since they are typically newlines
959  // that mess up our line tracking. These come from unknown pre-processor
960  // directives or hash-prefixed comments in standalone assembly files.
961  PP.Lex(Tok);
962  // FIXME: The token on the next line after #include should have
963  // Tok.isAtStartOfLine() set.
964  IsStartOfLine = true;
965  continue;
966  } else if (Tok.is(tok::annot_module_include)) {
967  // PrintPPOutputPPCallbacks::InclusionDirective handles producing
968  // appropriate output here. Ignore this token entirely.
969  PP.Lex(Tok);
970  IsStartOfLine = true;
971  continue;
972  } else if (Tok.is(tok::annot_module_begin)) {
973  // FIXME: We retrieve this token after the FileChanged callback, and
974  // retrieve the module_end token before the FileChanged callback, so
975  // we render this within the file and render the module end outside the
976  // file, but this is backwards from the token locations: the module_begin
977  // token is at the include location (outside the file) and the module_end
978  // token is at the EOF location (within the file).
979  Callbacks->BeginModule(
980  reinterpret_cast<Module *>(Tok.getAnnotationValue()));
981  PP.Lex(Tok);
982  IsStartOfLine = true;
983  continue;
984  } else if (Tok.is(tok::annot_module_end)) {
985  Callbacks->EndModule(
986  reinterpret_cast<Module *>(Tok.getAnnotationValue()));
987  PP.Lex(Tok);
988  IsStartOfLine = true;
989  continue;
990  } else if (Tok.is(tok::annot_header_unit)) {
991  // This is a header-name that has been (effectively) converted into a
992  // module-name.
993  // FIXME: The module name could contain non-identifier module name
994  // components. We don't have a good way to round-trip those.
995  Module *M = reinterpret_cast<Module *>(Tok.getAnnotationValue());
996  std::string Name = M->getFullModuleName();
997  Callbacks->OS->write(Name.data(), Name.size());
998  Callbacks->HandleNewlinesInToken(Name.data(), Name.size());
999  } else if (Tok.is(tok::annot_embed)) {
1000  // Manually explode the binary data out to a stream of comma-delimited
1001  // integer values. If the user passed -dE, that is handled by the
1002  // EmbedDirective() callback. We should only get here if the user did not
1003  // pass -dE.
1004  assert(Callbacks->expandEmbedContents() &&
1005  "did not expect an embed annotation");
1006  auto *Data =
1007  reinterpret_cast<EmbedAnnotationData *>(Tok.getAnnotationValue());
1008 
1009  // Loop over the contents and print them as a comma-delimited list of
1010  // values.
1011  bool PrintComma = false;
1012  for (auto Iter = Data->BinaryData.begin(), End = Data->BinaryData.end();
1013  Iter != End; ++Iter) {
1014  if (PrintComma)
1015  *Callbacks->OS << ", ";
1016  *Callbacks->OS << static_cast<unsigned>(*Iter);
1017  PrintComma = true;
1018  }
1019  } else if (Tok.isAnnotation()) {
1020  // Ignore annotation tokens created by pragmas - the pragmas themselves
1021  // will be reproduced in the preprocessed output.
1022  PP.Lex(Tok);
1023  continue;
1024  } else if (IdentifierInfo *II = Tok.getIdentifierInfo()) {
1025  *Callbacks->OS << II->getName();
1026  } else if (Tok.isLiteral() && !Tok.needsCleaning() &&
1027  Tok.getLiteralData()) {
1028  Callbacks->OS->write(Tok.getLiteralData(), Tok.getLength());
1029  } else if (Tok.getLength() < std::size(Buffer)) {
1030  const char *TokPtr = Buffer;
1031  unsigned Len = PP.getSpelling(Tok, TokPtr);
1032  Callbacks->OS->write(TokPtr, Len);
1033 
1034  // Tokens that can contain embedded newlines need to adjust our current
1035  // line number.
1036  // FIXME: The token may end with a newline in which case
1037  // setEmittedDirectiveOnThisLine/setEmittedTokensOnThisLine afterwards is
1038  // wrong.
1039  if (Tok.getKind() == tok::comment || Tok.getKind() == tok::unknown)
1040  Callbacks->HandleNewlinesInToken(TokPtr, Len);
1041  if (Tok.is(tok::comment) && Len >= 2 && TokPtr[0] == '/' &&
1042  TokPtr[1] == '/') {
1043  // It's a line comment;
1044  // Ensure that we don't concatenate anything behind it.
1045  Callbacks->setEmittedDirectiveOnThisLine();
1046  }
1047  } else {
1048  std::string S = PP.getSpelling(Tok);
1049  Callbacks->OS->write(S.data(), S.size());
1050 
1051  // Tokens that can contain embedded newlines need to adjust our current
1052  // line number.
1053  if (Tok.getKind() == tok::comment || Tok.getKind() == tok::unknown)
1054  Callbacks->HandleNewlinesInToken(S.data(), S.size());
1055  if (Tok.is(tok::comment) && S.size() >= 2 && S[0] == '/' && S[1] == '/') {
1056  // It's a line comment;
1057  // Ensure that we don't concatenate anything behind it.
1058  Callbacks->setEmittedDirectiveOnThisLine();
1059  }
1060  }
1061  Callbacks->setEmittedTokensOnThisLine();
1062  IsStartOfLine = false;
1063 
1064  if (Tok.is(tok::eof)) break;
1065 
1066  PP.Lex(Tok);
1067  // If lexing that token causes us to need to skip future tokens, do so now.
1068  for (unsigned I = 0, Skip = Callbacks->GetNumToksToSkip(); I < Skip; ++I)
1069  PP.Lex(Tok);
1070  Callbacks->ResetSkipToks();
1071  }
1072 }
1073 
1074 typedef std::pair<const IdentifierInfo *, MacroInfo *> id_macro_pair;
1075 static int MacroIDCompare(const id_macro_pair *LHS, const id_macro_pair *RHS) {
1076  return LHS->first->getName().compare(RHS->first->getName());
1077 }
1078 
1079 static void DoPrintMacros(Preprocessor &PP, raw_ostream *OS) {
1080  // Ignore unknown pragmas.
1081  PP.IgnorePragmas();
1082 
1083  // -dM mode just scans and ignores all tokens in the files, then dumps out
1084  // the macro table at the end.
1085  PP.EnterMainSourceFile();
1086 
1087  Token Tok;
1088  do PP.Lex(Tok);
1089  while (Tok.isNot(tok::eof));
1090 
1092  for (Preprocessor::macro_iterator I = PP.macro_begin(), E = PP.macro_end();
1093  I != E; ++I) {
1094  auto *MD = I->second.getLatest();
1095  if (MD && MD->isDefined())
1096  MacrosByID.push_back(id_macro_pair(I->first, MD->getMacroInfo()));
1097  }
1098  llvm::array_pod_sort(MacrosByID.begin(), MacrosByID.end(), MacroIDCompare);
1099 
1100  for (unsigned i = 0, e = MacrosByID.size(); i != e; ++i) {
1101  MacroInfo &MI = *MacrosByID[i].second;
1102  // Ignore computed macros like __LINE__ and friends.
1103  if (MI.isBuiltinMacro()) continue;
1104 
1105  PrintMacroDefinition(*MacrosByID[i].first, MI, PP, OS);
1106  *OS << '\n';
1107  }
1108 }
1109 
1110 /// DoPrintPreprocessedInput - This implements -E mode.
1111 ///
1113  const PreprocessorOutputOptions &Opts) {
1114  // Show macros with no output is handled specially.
1115  if (!Opts.ShowCPP) {
1116  assert(Opts.ShowMacros && "Not yet implemented!");
1117  DoPrintMacros(PP, OS);
1118  return;
1119  }
1120 
1121  // Inform the preprocessor whether we want it to retain comments or not, due
1122  // to -C or -CC.
1124 
1125  PrintPPOutputPPCallbacks *Callbacks = new PrintPPOutputPPCallbacks(
1126  PP, OS, !Opts.ShowLineMarkers, Opts.ShowMacros,
1129  Opts.KeepSystemIncludes);
1130 
1131  // Expand macros in pragmas with -fms-extensions. The assumption is that
1132  // the majority of pragmas in such a file will be Microsoft pragmas.
1133  // Remember the handlers we will add so that we can remove them later.
1134  std::unique_ptr<UnknownPragmaHandler> MicrosoftExtHandler(
1135  new UnknownPragmaHandler(
1136  "#pragma", Callbacks,
1137  /*RequireTokenExpansion=*/PP.getLangOpts().MicrosoftExt));
1138 
1139  std::unique_ptr<UnknownPragmaHandler> GCCHandler(new UnknownPragmaHandler(
1140  "#pragma GCC", Callbacks,
1141  /*RequireTokenExpansion=*/PP.getLangOpts().MicrosoftExt));
1142 
1143  std::unique_ptr<UnknownPragmaHandler> ClangHandler(new UnknownPragmaHandler(
1144  "#pragma clang", Callbacks,
1145  /*RequireTokenExpansion=*/PP.getLangOpts().MicrosoftExt));
1146 
1147  PP.AddPragmaHandler(MicrosoftExtHandler.get());
1148  PP.AddPragmaHandler("GCC", GCCHandler.get());
1149  PP.AddPragmaHandler("clang", ClangHandler.get());
1150 
1151  // The tokens after pragma omp need to be expanded.
1152  //
1153  // OpenMP [2.1, Directive format]
1154  // Preprocessing tokens following the #pragma omp are subject to macro
1155  // replacement.
1156  std::unique_ptr<UnknownPragmaHandler> OpenMPHandler(
1157  new UnknownPragmaHandler("#pragma omp", Callbacks,
1158  /*RequireTokenExpansion=*/true));
1159  PP.AddPragmaHandler("omp", OpenMPHandler.get());
1160 
1161  PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(Callbacks));
1162 
1163  // After we have configured the preprocessor, enter the main file.
1164  PP.EnterMainSourceFile();
1165  if (Opts.DirectivesOnly)
1167 
1168  // Consume all of the tokens that come from the predefines buffer. Those
1169  // should not be emitted into the output and are guaranteed to be at the
1170  // start.
1171  const SourceManager &SourceMgr = PP.getSourceManager();
1172  Token Tok;
1173  do {
1174  PP.Lex(Tok);
1175  if (Tok.is(tok::eof) || !Tok.getLocation().isFileID())
1176  break;
1177 
1178  PresumedLoc PLoc = SourceMgr.getPresumedLoc(Tok.getLocation());
1179  if (PLoc.isInvalid())
1180  break;
1181 
1182  if (strcmp(PLoc.getFilename(), "<built-in>"))
1183  break;
1184  } while (true);
1185 
1186  // Read all the preprocessed tokens, printing them out to the stream.
1187  PrintPreprocessedTokens(PP, Tok, Callbacks);
1188  *OS << '\n';
1189 
1190  if (!PP.getPreprocessorOpts().IncludeFooter.empty() &&
1191  !PP.IncludeFooterProcessed) {
1192  assert(PP.getLangOpts().SYCLIsHost &&
1193  "The 'include-footer' is expected in host compilation only");
1194  SourceLocation Loc = Tok.getLocation();
1196  Callbacks);
1197  }
1198 
1199  // Remove the handlers we just added to leave the preprocessor in a sane state
1200  // so that it can be reused (for example by a clang::Parser instance).
1201  PP.RemovePragmaHandler(MicrosoftExtHandler.get());
1202  PP.RemovePragmaHandler("GCC", GCCHandler.get());
1203  PP.RemovePragmaHandler("clang", ClangHandler.get());
1204  PP.RemovePragmaHandler("omp", OpenMPHandler.get());
1205 }
#define SM(sm)
Definition: Cuda.cpp:83
Defines the Diagnostic-related interfaces.
enum clang::sema::@1659::IndirectLocalPathEntry::EntryKind Kind
Expr * E
unsigned Iter
Definition: HTMLLogger.cpp:154
llvm::MachO::FileType FileType
Definition: MachO.h:46
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 void PrintIncludeFooter(Preprocessor &PP, SourceLocation Loc, std::string Footer, PrintPPOutputPPCallbacks *Callbacks)
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)
SourceLocation Loc
Definition: SemaObjC.cpp:759
Defines the SourceManager interface.
const char * Data
SourceLocation End
Represents a character-granular source range.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
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.
Record the location of an inclusion directive, such as an #include or #import statement.
A description of the current definition of a macro.
Definition: MacroInfo.h:590
MacroInfo * getMacroInfo() const
Get the MacroInfo that should be used for this definition.
Definition: MacroInfo.h:606
Encapsulates changes to the "macros namespace" (the location where the macro name became active,...
Definition: MacroInfo.h:313
const MacroInfo * getMacroInfo() const
Definition: MacroInfo.h:416
Encapsulates the data about a macro definition (e.g.
Definition: MacroInfo.h:39
bool isUsed() const
Return false if this macro is defined in the main file and has not yet been used.
Definition: MacroInfo.h:224
bool isFunctionLike() const
Definition: MacroInfo.h:201
const_tokens_iterator tokens_begin() const
Definition: MacroInfo.h:244
param_iterator param_begin() const
Definition: MacroInfo.h:182
bool isBuiltinMacro() const
Return true if this macro requires processing before expansion.
Definition: MacroInfo.h:217
IdentifierInfo *const * param_iterator
Parameters - The list of parameters for a function-like macro.
Definition: MacroInfo.h:180
SourceLocation getDefinitionLoc() const
Return the location that the macro was defined at.
Definition: MacroInfo.h:125
bool tokens_empty() const
Definition: MacroInfo.h:248
param_iterator param_end() const
Definition: MacroInfo.h:183
bool param_empty() const
Definition: MacroInfo.h:181
bool isGNUVarargs() const
Definition: MacroInfo.h:208
ArrayRef< Token > tokens() const
Definition: MacroInfo.h:249
Describes a module or submodule.
Definition: Module.h:105
std::string getFullModuleName(bool AllowStringLiterals=false) const
Retrieve the full name of this module, including the path from its top-level module.
Definition: Module.cpp:244
This interface provides a way to observe the actions of the preprocessor as it does its thing.
Definition: PPCallbacks.h:36
PragmaHandler - Instances of this interface defined to handle the various pragmas that the language f...
Definition: Pragma.h:65
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 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.
Definition: Preprocessor.h:137
PreprocessorOptions & getPreprocessorOpts() const
Retrieve the preprocessor options used to initialize this preprocessor.
void IgnorePragmas()
Install empty handlers for all pragmas (making them ignored).
Definition: Pragma.cpp:2196
SourceManager & getSourceManager() const
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
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.
Definition: Pragma.cpp:915
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 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.
Definition: Pragma.cpp:946
Represents an unpacked "presumed" location which can be presented to the user.
bool isValid() const
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.
Encodes a location in the source.
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.
StringRef getBufferData(FileID FID, bool *Invalid=nullptr) const
Return a StringRef to the source buffer data for the specified FileID.
FileID ComputeValidFooterFileID(StringRef Footer)
Get the file ID for the integration footer.
TokenConcatenation class, which answers the question of "Is it safe to emit two tokens without a whit...
bool AvoidConcat(const Token &PrevPrevTok, const Token &PrevTok, const Token &Tok) const
AvoidConcat - If printing PrevTok immediately followed by Tok would cause the two individual tokens t...
Token - This structure provides full information about a lexed token.
Definition: Token.h:36
bool isLiteral() const
Return true if this is a "literal", like a numeric constant, string, etc.
Definition: Token.h:116
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
Definition: Token.h:132
unsigned getLength() const
Definition: Token.h:135
void * getAnnotationValue() const
Definition: Token.h:234
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)) {....
Definition: Token.h:99
const char * getLiteralData() const
getLiteralData - For a literal token (numeric constant, string, etc), this returns a pointer to the s...
Definition: Token.h:225
tok::TokenKind getKind() const
Definition: Token.h:94
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
Definition: Token.h:276
IdentifierInfo * getIdentifierInfo() const
Definition: Token.h:187
bool hasLeadingSpace() const
Return true if this token has whitespace before it.
Definition: Token.h:280
bool isNot(tok::TokenKind K) const
Definition: Token.h:100
bool isAnnotation() const
Return true if this is any of tok::annot_* kind tokens.
Definition: Token.h:121
void startToken()
Reset all flags to cleared.
Definition: Token.h:177
bool needsCleaning() const
Return true if this token has trigraphs or escaped newlines in it.
Definition: Token.h:295
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
Definition: SourceManager.h:81
bool isSystem(CharacteristicKind CK)
Determine whether a file / directory characteristic is for system code.
Definition: SourceManager.h:90
Severity
Enum values that allow the client to map NOTEs, WARNINGs, and EXTENSIONs to either Ignore (nothing),...
Definition: DiagnosticIDs.h:85
@ Warning
Present this diagnostic as a warning.
@ Fatal
Present this diagnostic as a fatal error.
@ Error
Present this diagnostic as an error.
@ Remark
Present this diagnostic as a remark.
@ Ignored
Do not present this diagnostic, ignore it.
The JSON file list parser is used to communicate input to InstallAPI.
LLVM_READONLY bool isPrintable(unsigned char c)
Return true if this character is an ASCII printable character; that is, a character that should take ...
Definition: CharInfo.h:160
void DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream *OS, const PreprocessorOutputOptions &Opts)
DoPrintPreprocessedInput - Implement -E mode.
const FunctionProtoType * T
Helper class to shuttle information about #embed directives from the preprocessor to the parser throu...
std::optional< PPEmbedParameterIfEmpty > MaybeIfEmptyParam
std::optional< PPEmbedParameterOffset > MaybeOffsetParam
std::optional< PPEmbedParameterLimit > MaybeLimitParam
std::optional< PPEmbedParameterSuffix > MaybeSuffixParam
std::optional< PPEmbedParameterPrefix > MaybePrefixParam
Describes how and where the pragma was introduced.
Definition: Pragma.h:51