Coverage Report

Created: 2022-05-14 11:35

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