clang 24.0.0git
PrintPreprocessedOutput.cpp
Go to the documentation of this file.
1//===--- PrintPreprocessedOutput.cpp - Implement the -E mode --------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This code simply runs the preprocessor on the input file and prints out the
10// result. This is the traditional behavior of the -E option.
11//
12//===----------------------------------------------------------------------===//
13
19#include "clang/Lex/MacroInfo.h"
21#include "clang/Lex/Pragma.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()) {
43 for (; AI+1 != E; ++AI) {
44 *OS << (*AI)->getName();
45 *OS << ',';
46 }
47
48 // Last argument.
49 if ((*AI)->getName() == "__VA_ARGS__")
50 *OS << "...";
51 else
52 *OS << (*AI)->getName();
53 }
54
55 if (MI.isGNUVarargs())
56 *OS << "..."; // #define foo(x...)
57
58 *OS << ')';
59 }
60
61 // GCC always emits a space, even if the macro body is empty. However, do not
62 // want to emit two spaces if the first token has a leading space.
63 if (MI.tokens_empty() || !MI.tokens_begin()->hasLeadingSpace())
64 *OS << ' ';
65
66 SmallString<128> SpellingBuffer;
67 for (const auto &T : MI.tokens()) {
68 if (T.hasLeadingSpace())
69 *OS << ' ';
70
71 *OS << PP.getSpelling(T, SpellingBuffer);
72 }
73}
74
75//===----------------------------------------------------------------------===//
76// Preprocessed token printer
77//===----------------------------------------------------------------------===//
78
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;
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,
160 FileID PrevFID) override;
161 void EmbedDirective(SourceLocation HashLoc, StringRef FileName, bool IsAngled,
163 const LexEmbedParametersResult &Params) override;
164 void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
165 StringRef FileName, bool IsAngled,
166 CharSourceRange FilenameRange,
167 OptionalFileEntryRef File, StringRef SearchPath,
168 StringRef RelativePath, const Module *SuggestedModule,
169 bool ModuleImported,
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(Tok.getLocation());
214 unsigned TargetLine = PLoc.isValid() ? PLoc.getLine() : CurLine;
215 bool IsFirstInFile =
216 Tok.isAtStartOfLine() && PLoc.isValid() && PLoc.getLine() == 1;
217 return MoveToLine(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(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(Extra, ExtraLen);
274
276 OS->write(" 3", 2);
278 OS->write(" 3 4", 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(NewLines, LineNo - CurLine);
318 } else {
319 // Emit a #line or line marker.
320 WriteLineInfo(LineNo, nullptr, 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(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(FileType) != isSystem(NewFileType)))
381 OS = isSystem(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(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) {
409 WriteLineInfo(CurLine, " 1", 2);
410 break;
412 WriteLineInfo(CurLine, " 2", 2);
413 break;
416 WriteLineInfo(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(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(T, 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(FileType))) {
497 MoveToLine(HashLoc, /*RequireStartOfLine=*/true);
498 const std::string TokenText = PP.getSpelling(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(HashLoc, /*RequireStartOfLine=*/true);
515 *OS << "#pragma clang module import "
516 << SuggestedModule->getFullModuleName(true)
517 << " /* clang -E: implicit import for "
518 << "#" << PP.getSpelling(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(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(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("#ident ", strlen("#ident "));
559 OS->write(S.begin(), 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(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(MacroName)) {
588 MoveToLine(DefLoc, /*RequireStartOfLine=*/true);
589 *OS << "#pragma clang __set_pp_state " << MacroName->getName();
590 PrintMacroDefinition(/*II=*/nullptr, *MI, PP, OS);
591 setEmittedDirectiveOnThisLine();
592 }
593 return;
594 }
595
596 MoveToLine(DefLoc, /*RequireStartOfLine=*/true);
597 PrintMacroDefinition(MacroName, *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(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(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(tok::eof) ||
790 (Tok.isAnnotation() && !Tok.is(tok::annot_header_unit) &&
791 !Tok.is(tok::annot_module_begin) && !Tok.is(tok::annot_module_end) &&
792 !Tok.is(tok::annot_repl_input_end) && !Tok.is(tok::annot_embed) &&
793 !Tok.is(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(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(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(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(PragmaTok.getLocation(), /*RequireStartOfLine=*/true);
887 Callbacks->OS->write(Prefix, strlen(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[]>(1);
894 Toks[0] = PragmaTok;
895 PP.EnterTokenStream(std::move(Toks), /*NumToks=*/1,
896 /*DisableMacroExpansion=*/false,
897 /*IsReinject=*/false);
898 PP.Lex(PragmaTok);
899 }
900
901 // Read and print all of the pragma tokens.
902 bool IsFirst = true;
903 while (PragmaTok.isNot(tok::eod)) {
904 Callbacks->HandleWhitespaceBeforeTok(PragmaTok, /*RequireSpace=*/IsFirst,
905 /*RequireSameLine=*/true);
906 IsFirst = false;
907 std::string TokSpell = PP.getSpelling(PragmaTok);
908 Callbacks->OS->write(&TokSpell[0], TokSpell.size());
909 Callbacks->setEmittedTokensOnThisLine();
910
911 if (ShouldExpandTokens)
912 PP.Lex(PragmaTok);
913 else
914 PP.LexUnexpandedToken(PragmaTok);
915 }
916 Callbacks->setEmittedDirectiveOnThisLine();
917 }
918};
919} // end anonymous namespace
920
921
923 PrintPPOutputPPCallbacks *Callbacks) {
924 bool DropComments = PP.getLangOpts().TraditionalCPP &&
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(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(Tok);
948 continue;
949 } else if (Tok.is(tok::annot_repl_input_end)) {
950 // Fall through to exit the loop.
951 } else if (Tok.is(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(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(tok::annot_module_include)) {
961 // PrintPPOutputPPCallbacks::InclusionDirective handles producing
962 // appropriate output here. Ignore this token entirely.
963 PP.Lex(Tok);
964 IsStartOfLine = true;
965 continue;
966 } else if (Tok.is(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 reinterpret_cast<Module *>(Tok.getAnnotationValue()));
975 PP.Lex(Tok);
976 IsStartOfLine = true;
977 continue;
978 } else if (Tok.is(tok::annot_module_end)) {
979 Callbacks->EndModule(
980 reinterpret_cast<Module *>(Tok.getAnnotationValue()));
981 PP.Lex(Tok);
982 IsStartOfLine = true;
983 continue;
984 } else if (Tok.is(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(Name);
994 *Callbacks->OS << '"';
995 } else if (Tok.is(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(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(Tok);
1021 continue;
1022 } else if (PP.getLangOpts().CPlusPlusModules && Tok.is(tok::kw_import) &&
1023 !Callbacks->GetPrevToken().is(tok::at)) {
1024 assert(!IsCXXModuleDirective && "Is an import directive being printed?");
1025 IsCXXModuleDirective = true;
1026 IsStartOfLine = false;
1027 *Callbacks->OS << tok::getPPKeywordSpelling(
1028 tok::pp___preprocessed_import);
1029 PP.Lex(Tok);
1030 continue;
1031 } else if (PP.getLangOpts().CPlusPlusModules && Tok.is(tok::kw_module)) {
1032 assert(!IsCXXModuleDirective && "Is an module directive being printed?");
1033 IsCXXModuleDirective = true;
1034 IsStartOfLine = false;
1035 *Callbacks->OS << tok::getPPKeywordSpelling(
1036 tok::pp___preprocessed_module);
1037 PP.Lex(Tok);
1038 continue;
1039 } else if (PP.getLangOpts().CPlusPlusModules && IsCXXModuleDirective &&
1040 Tok.is(tok::semi)) {
1041 IsCXXModuleDirective = false;
1042 IsStartOfLine = true;
1043 *Callbacks->OS << ';';
1044 PP.Lex(Tok);
1045 continue;
1046 } else if (IdentifierInfo *II = Tok.getIdentifierInfo()) {
1047 *Callbacks->OS << II->getName();
1048 } else if (Tok.isLiteral() && !Tok.needsCleaning() &&
1049 Tok.getLiteralData()) {
1050 Callbacks->OS->write(Tok.getLiteralData(), Tok.getLength());
1051 } else if (Tok.getLength() < std::size(Buffer)) {
1052 const char *TokPtr = Buffer;
1053 unsigned Len = PP.getSpelling(Tok, TokPtr);
1054 Callbacks->OS->write(TokPtr, Len);
1055
1056 // Tokens that can contain embedded newlines need to adjust our current
1057 // line number.
1058 // FIXME: The token may end with a newline in which case
1059 // setEmittedDirectiveOnThisLine/setEmittedTokensOnThisLine afterwards is
1060 // wrong.
1061 if (Tok.getKind() == tok::comment || Tok.getKind() == tok::unknown)
1062 Callbacks->HandleNewlinesInToken(TokPtr, Len);
1063 if (Tok.is(tok::comment) && Len >= 2 && TokPtr[0] == '/' &&
1064 TokPtr[1] == '/') {
1065 // It's a line comment;
1066 // Ensure that we don't concatenate anything behind it.
1067 Callbacks->setEmittedDirectiveOnThisLine();
1068 }
1069 } else {
1070 std::string S = PP.getSpelling(Tok);
1071 Callbacks->OS->write(S.data(), S.size());
1072
1073 // Tokens that can contain embedded newlines need to adjust our current
1074 // line number.
1075 if (Tok.getKind() == tok::comment || Tok.getKind() == tok::unknown)
1076 Callbacks->HandleNewlinesInToken(S.data(), S.size());
1077 if (Tok.is(tok::comment) && S.size() >= 2 && S[0] == '/' && S[1] == '/') {
1078 // It's a line comment;
1079 // Ensure that we don't concatenate anything behind it.
1080 Callbacks->setEmittedDirectiveOnThisLine();
1081 }
1082 }
1083 Callbacks->setEmittedTokensOnThisLine();
1084 IsStartOfLine = false;
1085
1086 if (Tok.is(tok::eof) || Tok.is(tok::annot_repl_input_end))
1087 break;
1088
1089 PP.Lex(Tok);
1090 // If lexing that token causes us to need to skip future tokens, do so now.
1091 for (unsigned I = 0, Skip = Callbacks->GetNumToksToSkip(); I < Skip; ++I)
1092 PP.Lex(Tok);
1093 Callbacks->ResetSkipToks();
1094 }
1095}
1096
1097typedef std::pair<const IdentifierInfo *, MacroInfo *> id_macro_pair;
1098static int MacroIDCompare(const id_macro_pair *LHS, const id_macro_pair *RHS) {
1099 return LHS->first->getName().compare(RHS->first->getName());
1100}
1101
1102static void DoPrintMacros(Preprocessor &PP, raw_ostream *OS) {
1103 // Ignore unknown pragmas.
1104 PP.IgnorePragmas();
1105
1106 // -dM mode just scans and ignores all tokens in the files, then dumps out
1107 // the macro table at the end.
1109
1110 PP.LexTokensUntilEOF();
1111
1113 for (const auto &M : PP.macros()) {
1114 auto *MD = M.second.getLatest();
1115 if (MD && MD->isDefined())
1116 MacrosByID.push_back(id_macro_pair(M.first, MD->getMacroInfo()));
1117 }
1118 llvm::array_pod_sort(MacrosByID.begin(), MacrosByID.end(), MacroIDCompare);
1119
1120 for (unsigned i = 0, e = MacrosByID.size(); i != e; ++i) {
1121 MacroInfo &MI = *MacrosByID[i].second;
1122 // Ignore computed macros like __LINE__ and friends.
1123 if (MI.isBuiltinMacro()) continue;
1124
1125 PrintMacroDefinition(MacrosByID[i].first, MI, PP, OS);
1126 *OS << '\n';
1127 }
1128}
1129
1130/// DoPrintPreprocessedInput - This implements -E mode.
1131///
1133 const PreprocessorOutputOptions &Opts) {
1134 // Show macros with no output is handled specially.
1135 if (!Opts.ShowCPP) {
1136 assert(Opts.ShowMacros && "Not yet implemented!");
1137 DoPrintMacros(PP, OS);
1138 return;
1139 }
1140
1141 // Inform the preprocessor whether we want it to retain comments or not, due
1142 // to -C or -CC.
1144
1145 PrintPPOutputPPCallbacks *Callbacks = new PrintPPOutputPPCallbacks(
1146 PP, OS, !Opts.ShowLineMarkers, Opts.ShowMacros,
1149 Opts.KeepSystemIncludes);
1150
1151 // Expand macros in pragmas with -fms-extensions. The assumption is that
1152 // the majority of pragmas in such a file will be Microsoft pragmas.
1153 // Remember the handlers we will add so that we can remove them later.
1154 std::unique_ptr<UnknownPragmaHandler> MicrosoftExtHandler(
1155 new UnknownPragmaHandler(
1156 "#pragma", Callbacks,
1157 /*RequireTokenExpansion=*/PP.getLangOpts().MicrosoftExt));
1158
1159 std::unique_ptr<UnknownPragmaHandler> GCCHandler(new UnknownPragmaHandler(
1160 "#pragma GCC", Callbacks,
1161 /*RequireTokenExpansion=*/PP.getLangOpts().MicrosoftExt));
1162
1163 std::unique_ptr<UnknownPragmaHandler> ClangHandler(new UnknownPragmaHandler(
1164 "#pragma clang", Callbacks,
1165 /*RequireTokenExpansion=*/PP.getLangOpts().MicrosoftExt));
1166
1167 PP.AddPragmaHandler(MicrosoftExtHandler.get());
1168 PP.AddPragmaHandler("GCC", GCCHandler.get());
1169 PP.AddPragmaHandler("clang", ClangHandler.get());
1170
1171 // The tokens after pragma omp need to be expanded.
1172 //
1173 // OpenMP [2.1, Directive format]
1174 // Preprocessing tokens following the #pragma omp are subject to macro
1175 // replacement.
1176 std::unique_ptr<UnknownPragmaHandler> OpenMPHandler(
1177 new UnknownPragmaHandler("#pragma omp", Callbacks,
1178 /*RequireTokenExpansion=*/true));
1179 PP.AddPragmaHandler("omp", OpenMPHandler.get());
1180
1181 PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(Callbacks));
1182
1183 // After we have configured the preprocessor, enter the main file.
1185 if (Opts.DirectivesOnly)
1187
1188 // Consume all of the tokens that come from the predefines buffer. Those
1189 // should not be emitted into the output and are guaranteed to be at the
1190 // start.
1191 const SourceManager &SourceMgr = PP.getSourceManager();
1192 Token Tok;
1193 do {
1194 PP.Lex(Tok);
1195 if (Tok.is(tok::eof) || !Tok.getLocation().isFileID())
1196 break;
1197
1198 PresumedLoc PLoc = SourceMgr.getPresumedLoc(Tok.getLocation());
1199 if (PLoc.isInvalid())
1200 break;
1201
1202 if (strcmp(PLoc.getFilename(), "<built-in>"))
1203 break;
1204 } while (true);
1205
1206 // Read all the preprocessed tokens, printing them out to the stream.
1207 PrintPreprocessedTokens(PP, Tok, Callbacks);
1208 *OS << '\n';
1209
1210 // Remove the handlers we just added to leave the preprocessor in a sane state
1211 // so that it can be reused (for example by a clang::Parser instance).
1212 PP.RemovePragmaHandler(MicrosoftExtHandler.get());
1213 PP.RemovePragmaHandler("GCC", GCCHandler.get());
1214 PP.RemovePragmaHandler("clang", ClangHandler.get());
1215 PP.RemovePragmaHandler("omp", OpenMPHandler.get());
1216}
Defines the Diagnostic-related interfaces.
StringRef TokenText
The raw text of the token.
Token Tok
The Token.
unsigned IsFirst
Indicates that this is the first token of the file.
llvm::MachO::FileType FileType
Definition MachO.h:46
Defines the clang::MacroInfo and clang::MacroDirective classes.
Defines the PPCallbacks interface.
Defines the clang::Preprocessor interface.
static void PrintMacroDefinition(const IdentifierInfo *II, const MacroInfo &MI, Preprocessor &PP, raw_ostream *OS)
PrintMacroDefinition - Print a macro definition in a form that will be properly accepted back as a de...
std::pair< const IdentifierInfo *, MacroInfo * > id_macro_pair
static void DoPrintMacros(Preprocessor &PP, raw_ostream *OS)
static int MacroIDCompare(const id_macro_pair *LHS, const id_macro_pair *RHS)
static void PrintPreprocessedTokens(Preprocessor &PP, Token &Tok, PrintPPOutputPPCallbacks *Callbacks)
static void outputPrintable(raw_ostream *OS, StringRef Str)
Defines the SourceManager interface.
One of these records is kept for each identifier that is lexed.
tok::PPKeywordKind getPPKeywordID() const
Return the preprocessor keyword ID for this identifier.
StringRef getName() const
Return the actual identifier string.
MacroInfo * getMacroInfo() const
Get the MacroInfo that should be used for this definition.
Definition MacroInfo.h:612
const MacroInfo * getMacroInfo() const
Definition MacroInfo.h:417
Encapsulates the data about a macro definition (e.g.
Definition MacroInfo.h:40
bool isUsed() const
Return false if this macro is defined in the main file and has not yet been used.
Definition MacroInfo.h:225
bool isFunctionLike() const
Definition MacroInfo.h:202
const_tokens_iterator tokens_begin() const
Definition MacroInfo.h:245
param_iterator param_begin() const
Definition MacroInfo.h:183
bool isBuiltinMacro() const
Return true if this macro requires processing before expansion.
Definition MacroInfo.h:218
IdentifierInfo *const * param_iterator
Parameters - The list of parameters for a function-like macro.
Definition MacroInfo.h:181
SourceLocation getDefinitionLoc() const
Return the location that the macro was defined at.
Definition MacroInfo.h:126
bool tokens_empty() const
Definition MacroInfo.h:249
param_iterator param_end() const
Definition MacroInfo.h:184
bool param_empty() const
Definition MacroInfo.h:182
ArrayRef< Token > tokens() const
Definition MacroInfo.h:250
bool isGNUVarargs() const
Definition MacroInfo.h:209
Describes a module or submodule.
Definition Module.h:340
std::string getFullModuleName(bool AllowStringLiterals=false) const
Retrieve the full name of this module, including the path from its top-level module.
Definition Module.cpp:240
This interface provides a way to observe the actions of the preprocessor as it does its thing.
Definition PPCallbacks.h:37
PreprocessorOutputOptions - Options for controlling the C preprocessor output (e.g....
unsigned UseLineDirectives
Use #line instead of GCC-style # N.
unsigned ShowMacros
Print macro definitions.
unsigned ShowIncludeDirectives
Print includes, imports etc. within preprocessed output.
unsigned ShowMacroComments
Show comments, even in macros.
unsigned ShowCPP
Print normal preprocessed output.
unsigned MinimizeWhitespace
Ignore whitespace from input.
unsigned KeepSystemIncludes
Do not expand system headers.
unsigned ShowEmbedDirectives
Print embeds, etc. within preprocessed.
unsigned ShowLineMarkers
Show #line markers.
unsigned DirectivesOnly
Process directives but do not expand macros.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
bool isPragmaSetPPStateMacro(IdentifierInfo *II)
Check whether this is a macro name that can be used as an argument to 'pragma clang __set_pp_state'.
Definition Pragma.cpp:916
void IgnorePragmas()
Install empty handlers for all pragmas (making them ignored).
Definition Pragma.cpp:2280
llvm::iterator_range< macro_iterator > macros(bool IncludeExternalMacros=true) const
void Lex(Token &Result)
Lex the next token for this preprocessor.
void addPPCallbacks(std::unique_ptr< PPCallbacks > C)
void EnterMainSourceFile()
Enter the specified FileID as the main source file, which implicitly adds the builtin defines etc.
SourceManager & getSourceManager() const
bool getCommentRetentionState() const
void SetMacroExpansionOnlyInDirectives()
Disables macro expansion everywhere except for preprocessor directives.
void LexUnexpandedToken(Token &Result)
Just like Lex, but disables macro expansion of identifier tokens.
void AddPragmaHandler(StringRef Namespace, PragmaHandler *Handler)
Add the specified pragma handler to this preprocessor.
Definition Pragma.cpp:960
StringRef getSpelling(SourceLocation loc, SmallVectorImpl< char > &buffer, bool *invalid=nullptr) const
Return the 'spelling' of the token at the given location; does not go up to the spelling location or ...
const LangOptions & getLangOpts() const
void LexTokensUntilEOF(std::vector< Token > *Tokens=nullptr)
Lex all tokens for this preprocessor until (and excluding) end of file.
void SetCommentRetentionState(bool KeepComments, bool KeepMacroComments)
Control whether the preprocessor retains comments in output.
void RemovePragmaHandler(StringRef Namespace, PragmaHandler *Handler)
Remove the specific pragma handler from this preprocessor.
Definition Pragma.cpp:991
Represents an unpacked "presumed" location which can be presented to the user.
const char * getFilename() const
Return the presumed filename of this location.
unsigned getLine() const
Return the presumed line number of this location.
bool isInvalid() const
Return true if this object is invalid or uninitialized.
SourceLocation getIncludeLoc() const
Return the presumed include location of this location.
bool isValid() const
Return true if this is a valid SourceLocation object.
This class handles loading and caching of source files into memory.
bool isInPredefinedFile(SourceLocation Loc) const
Returns whether Loc is located in a built-in or command line source.
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
unsigned getExpansionColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const
Token - This structure provides full information about a lexed token.
Definition Token.h:36
IdentifierInfo * getIdentifierInfo() const
Definition Token.h:197
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
Definition Token.h:142
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
Definition Token.h:104
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
Definition Token.h:286
bool hasLeadingSpace() const
Return true if this token has whitespace before it.
Definition Token.h:294
bool isNot(tok::TokenKind K) const
Definition Token.h:111
bool isAnnotation() const
Return true if this is any of tok::annot_* kind tokens.
Definition Token.h:131
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
bool isSystem(CharacteristicKind CK)
Determine whether a file / directory characteristic is for system code.
Severity
Enum values that allow the client to map NOTEs, WARNINGs, and EXTENSIONs to either Ignore (nothing),...
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
const char * getPPKeywordSpelling(PPKeywordKind Kind) LLVM_READNONE
Returns the spelling of preprocessor keywords, such as "else".
Top level wrappers for InstallAPI frontend operations.
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
Definition FileEntry.h:196
LLVM_READONLY bool isPrintable(unsigned char c)
Return true if this character is an ASCII printable character; that is, a character that should take ...
Definition CharInfo.h:160
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
Definition Linkage.h:54
const FunctionProtoType * T
void DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream *OS, const PreprocessorOutputOptions &Opts)
DoPrintPreprocessedInput - Implement -E mode.
Helper class to shuttle information about embed directives from the preprocessor to the parser throug...
std::optional< PPEmbedParameterIfEmpty > MaybeIfEmptyParam
std::optional< PPEmbedParameterOffset > MaybeOffsetParam
std::optional< PPEmbedParameterLimit > MaybeLimitParam
std::optional< PPEmbedParameterSuffix > MaybeSuffixParam
std::optional< PPEmbedParameterPrefix > MaybePrefixParam