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