Coverage Report

Created: 2024-01-17 10:31

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