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