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