Coverage Report

Created: 2021-09-21 08:58

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