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