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"
37 *OS <<
"#define " << II->
getName();
43 for (; AI+1 != E; ++AI) {
44 *OS << (*AI)->getName();
49 if ((*AI)->getName() ==
"__VA_ARGS__")
52 *OS << (*AI)->getName();
67 for (
const auto &
T : MI.
tokens()) {
68 if (
T.hasLeadingSpace())
80class PrintPPOutputPPCallbacks :
public PPCallbacks {
83 TokenConcatenation ConcatInfo;
89 bool EmittedTokensOnThisLine;
90 bool EmittedDirectiveOnThisLine;
92 SmallString<512> CurFilename;
94 bool DisableLineMarkers;
96 bool DumpIncludeDirectives;
97 bool DumpEmbedDirectives;
98 bool UseLineDirectives;
99 bool IsFirstFileEntered;
100 bool MinimizeWhitespace;
102 bool KeepSystemIncludes;
104 std::unique_ptr<llvm::raw_null_ostream> NullOS;
105 unsigned NumToksToSkip;
111 PrintPPOutputPPCallbacks(Preprocessor &pp, raw_ostream *os,
bool lineMarkers,
112 bool defines,
bool DumpIncludeDirectives,
113 bool DumpEmbedDirectives,
bool UseLineDirectives,
114 bool MinimizeWhitespace,
bool DirectivesOnly,
115 bool KeepSystemIncludes)
116 : PP(pp), SM(PP.getSourceManager()), ConcatInfo(PP), OS(os),
117 DisableLineMarkers(lineMarkers), DumpDefines(defines),
118 DumpIncludeDirectives(DumpIncludeDirectives),
119 DumpEmbedDirectives(DumpEmbedDirectives),
120 UseLineDirectives(UseLineDirectives),
121 MinimizeWhitespace(MinimizeWhitespace), DirectivesOnly(DirectivesOnly),
122 KeepSystemIncludes(KeepSystemIncludes), OrigOS(os), NumToksToSkip(0) {
124 CurFilename +=
"<uninit>";
125 EmittedTokensOnThisLine =
false;
126 EmittedDirectiveOnThisLine =
false;
129 IsFirstFileEntered =
false;
130 if (KeepSystemIncludes)
131 NullOS = std::make_unique<llvm::raw_null_ostream>();
133 PrevTok.startToken();
134 PrevPrevTok.startToken();
139 bool expandEmbedContents()
const {
return !DumpEmbedDirectives; }
141 bool isMinimizeWhitespace()
const {
return MinimizeWhitespace; }
143 void setEmittedTokensOnThisLine() { EmittedTokensOnThisLine =
true; }
144 bool hasEmittedTokensOnThisLine()
const {
return EmittedTokensOnThisLine; }
146 void setEmittedDirectiveOnThisLine() { EmittedDirectiveOnThisLine =
true; }
147 bool hasEmittedDirectiveOnThisLine()
const {
148 return EmittedDirectiveOnThisLine;
156 void startNewLineIfNeeded();
158 void FileChanged(SourceLocation Loc, FileChangeReason Reason,
160 FileID PrevFID)
override;
161 void EmbedDirective(SourceLocation HashLoc, StringRef
FileName,
bool IsAngled,
163 const LexEmbedParametersResult &Params)
override;
164 void InclusionDirective(SourceLocation HashLoc,
const Token &IncludeTok,
166 CharSourceRange FilenameRange,
168 StringRef RelativePath,
const Module *SuggestedModule,
171 void Ident(SourceLocation Loc, StringRef str)
override;
172 void PragmaMessage(SourceLocation Loc, StringRef Namespace,
173 PragmaMessageKind Kind, StringRef Str)
override;
174 void PragmaDebug(SourceLocation Loc, StringRef DebugType)
override;
175 void PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace)
override;
176 void PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace)
override;
177 void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
179 void PragmaWarning(SourceLocation Loc, PragmaWarningSpecifier WarningSpec,
180 ArrayRef<int> Ids)
override;
181 void PragmaWarningPush(SourceLocation Loc,
int Level)
override;
182 void PragmaWarningPop(SourceLocation Loc)
override;
183 void PragmaExecCharsetPush(SourceLocation Loc, StringRef Str)
override;
184 void PragmaExecCharsetPop(SourceLocation Loc)
override;
185 void PragmaAssumeNonNullBegin(SourceLocation Loc)
override;
186 void PragmaAssumeNonNullEnd(SourceLocation Loc)
override;
187 void PragmaSetPPState(SourceLocation Loc, IdentifierInfo *MacroName,
188 std::uint64_t
Value)
override;
197 void HandleWhitespaceBeforeTok(
const Token &
Tok,
bool RequireSpace,
198 bool RequireSameLine);
212 bool MoveToLine(
const Token &
Tok,
bool RequireStartOfLine) {
217 return MoveToLine(TargetLine, RequireStartOfLine) || IsFirstInFile;
222 bool MoveToLine(SourceLocation Loc,
bool RequireStartOfLine) {
223 PresumedLoc PLoc = SM.getPresumedLoc(Loc);
225 return MoveToLine(TargetLine, RequireStartOfLine);
227 bool MoveToLine(
unsigned LineNo,
bool RequireStartOfLine);
229 bool AvoidConcat(
const Token &PrevPrevTok,
const Token &PrevTok,
231 return ConcatInfo.AvoidConcat(PrevPrevTok, PrevTok,
Tok);
233 void WriteLineInfo(
unsigned LineNo,
const char *
Extra=
nullptr,
234 unsigned ExtraLen=0);
235 bool LineMarkersAreDisabled()
const {
return DisableLineMarkers; }
236 void HandleNewlinesInToken(
const char *TokStr,
unsigned Len);
239 void MacroDefined(
const Token &MacroNameTok,
240 const MacroDirective *MD)
override;
243 void MacroUndefined(
const Token &MacroNameTok,
244 const MacroDefinition &MD,
245 const MacroDirective *Undef)
override;
247 void BeginModule(
const Module *M);
248 void EndModule(
const Module *M);
250 unsigned GetNumToksToSkip()
const {
return NumToksToSkip; }
251 void ResetSkipToks() { NumToksToSkip = 0; }
253 const Token &GetPrevToken()
const {
return PrevTok; }
257void PrintPPOutputPPCallbacks::WriteLineInfo(
unsigned LineNo,
260 startNewLineIfNeeded();
263 if (UseLineDirectives) {
264 *
OS <<
"#line" <<
' ' << LineNo <<
' ' <<
'"';
268 *
OS <<
'#' <<
' ' << LineNo <<
' ' <<
'"';
278 OS->write(
" 3 4", 4);
287bool PrintPPOutputPPCallbacks::MoveToLine(
unsigned LineNo,
288 bool RequireStartOfLine) {
292 bool StartedNewLine =
false;
293 if ((RequireStartOfLine && EmittedTokensOnThisLine) ||
294 EmittedDirectiveOnThisLine) {
296 StartedNewLine =
true;
298 EmittedTokensOnThisLine =
false;
299 EmittedDirectiveOnThisLine =
false;
304 if (CurLine == LineNo) {
306 }
else if (MinimizeWhitespace && DisableLineMarkers) {
308 }
else if (!StartedNewLine && LineNo - CurLine == 1) {
313 StartedNewLine =
true;
314 }
else if (!DisableLineMarkers) {
315 if (LineNo - CurLine <= 8) {
316 const char *NewLines =
"\n\n\n\n\n\n\n\n";
317 OS->write(NewLines, LineNo - CurLine);
320 WriteLineInfo(LineNo,
nullptr, 0);
322 StartedNewLine =
true;
323 }
else if (EmittedTokensOnThisLine) {
327 StartedNewLine =
true;
330 if (StartedNewLine) {
331 EmittedTokensOnThisLine =
false;
332 EmittedDirectiveOnThisLine =
false;
336 return StartedNewLine;
339void PrintPPOutputPPCallbacks::startNewLineIfNeeded() {
340 if (EmittedTokensOnThisLine || EmittedDirectiveOnThisLine) {
342 EmittedTokensOnThisLine =
false;
343 EmittedDirectiveOnThisLine =
false;
350void PrintPPOutputPPCallbacks::FileChanged(SourceLocation Loc,
351 FileChangeReason Reason,
356 SourceManager &SourceMgr = SM;
362 unsigned NewLine = UserLoc.
getLine();
367 MoveToLine(IncludeLoc,
false);
387 if (DisableLineMarkers) {
388 if (!MinimizeWhitespace)
389 startNewLineIfNeeded();
394 WriteLineInfo(CurLine);
403 IsFirstFileEntered =
true;
409 WriteLineInfo(CurLine,
" 1", 2);
412 WriteLineInfo(CurLine,
" 2", 2);
416 WriteLineInfo(CurLine);
421void PrintPPOutputPPCallbacks::EmbedDirective(
422 SourceLocation HashLoc, StringRef
FileName,
bool IsAngled,
424 if (!DumpEmbedDirectives)
437 MoveToLine(HashLoc,
true);
438 *
OS <<
"#embed " << (IsAngled ?
'<' :
'"') <<
FileName
439 << (IsAngled ?
'>' :
'"');
441 auto PrintToks = [&](llvm::ArrayRef<Token> Toks) {
442 SmallString<128> SpellingBuffer;
443 for (
const Token &
T : Toks) {
444 if (
T.hasLeadingSpace())
449 bool SkipAnnotToks =
true;
458 SkipAnnotToks =
false;
485 *
OS <<
" /* clang -E -dE */";
486 setEmittedDirectiveOnThisLine();
489void PrintPPOutputPPCallbacks::InclusionDirective(
490 SourceLocation HashLoc,
const Token &IncludeTok, StringRef
FileName,
492 StringRef SearchPath, StringRef RelativePath,
const Module *SuggestedModule,
497 MoveToLine(HashLoc,
true);
501 << (IsAngled ?
'<' :
'"') <<
FileName << (IsAngled ?
'>' :
'"')
503 << (DumpIncludeDirectives ?
"-dI" :
"-fkeep-system-includes")
505 setEmittedDirectiveOnThisLine();
509 if (ModuleImported) {
511 case tok::pp_include:
513 case tok::pp_include_next:
514 MoveToLine(HashLoc,
true);
515 *
OS <<
"#pragma clang module import "
517 <<
" /* clang -E: implicit import for "
519 << (IsAngled ?
'<' :
'"') <<
FileName << (IsAngled ?
'>' :
'"')
521 setEmittedDirectiveOnThisLine();
524 case tok::pp___include_macros:
533 llvm_unreachable(
"unknown include directive kind");
540void PrintPPOutputPPCallbacks::BeginModule(
const Module *M) {
541 startNewLineIfNeeded();
543 setEmittedDirectiveOnThisLine();
547void PrintPPOutputPPCallbacks::EndModule(
const Module *M) {
548 startNewLineIfNeeded();
550 setEmittedDirectiveOnThisLine();
555void PrintPPOutputPPCallbacks::Ident(SourceLocation Loc, StringRef S) {
556 MoveToLine(Loc,
true);
558 OS->write(
"#ident ", strlen(
"#ident "));
559 OS->write(S.begin(), S.size());
560 setEmittedTokensOnThisLine();
564void PrintPPOutputPPCallbacks::MacroDefined(
const Token &MacroNameTok,
565 const MacroDirective *MD) {
566 bool ShouldEmitDefine =
true;
572 if ((!DumpDefines && !DirectivesOnly) ||
575 ShouldEmitDefine =
false;
576 }
else if (DirectivesOnly && !MI->
isUsed()) {
579 ShouldEmitDefine =
false;
583 if (!ShouldEmitDefine) {
588 MoveToLine(DefLoc,
true);
589 *
OS <<
"#pragma clang __set_pp_state " << MacroName->
getName();
591 setEmittedDirectiveOnThisLine();
596 MoveToLine(DefLoc,
true);
598 setEmittedDirectiveOnThisLine();
601void PrintPPOutputPPCallbacks::MacroUndefined(
const Token &MacroNameTok,
602 const MacroDefinition &MD,
603 const MacroDirective *Undef) {
606 if (!DumpDefines && !DirectivesOnly)
611 setEmittedDirectiveOnThisLine();
615 for (
unsigned char Char : Str) {
616 if (
isPrintable(Char) && Char !=
'\\' && Char !=
'"')
620 << (char)(
'0' + ((Char >> 6) & 7))
621 << (char)(
'0' + ((Char >> 3) & 7))
622 << (char)(
'0' + ((Char >> 0) & 7));
626void PrintPPOutputPPCallbacks::PragmaMessage(SourceLocation Loc,
628 PragmaMessageKind Kind,
630 MoveToLine(Loc,
true);
648 if (Kind == PMK_Message)
650 setEmittedDirectiveOnThisLine();
653void PrintPPOutputPPCallbacks::PragmaDebug(SourceLocation Loc,
654 StringRef DebugType) {
655 MoveToLine(Loc,
true);
657 *
OS <<
"#pragma clang __debug ";
660 setEmittedDirectiveOnThisLine();
663void PrintPPOutputPPCallbacks::
664PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace) {
665 MoveToLine(Loc,
true);
666 *
OS <<
"#pragma " <<
Namespace <<
" diagnostic push";
667 setEmittedDirectiveOnThisLine();
670void PrintPPOutputPPCallbacks::
671PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace) {
672 MoveToLine(Loc,
true);
673 *
OS <<
"#pragma " <<
Namespace <<
" diagnostic pop";
674 setEmittedDirectiveOnThisLine();
677void PrintPPOutputPPCallbacks::PragmaDiagnostic(SourceLocation Loc,
681 MoveToLine(Loc,
true);
684 case diag::Severity::Remark:
687 case diag::Severity::Warning:
690 case diag::Severity::Error:
693 case diag::Severity::Ignored:
696 case diag::Severity::Fatal:
700 *
OS <<
" \"" << Str <<
'"';
701 setEmittedDirectiveOnThisLine();
704void PrintPPOutputPPCallbacks::PragmaWarning(SourceLocation Loc,
705 PragmaWarningSpecifier WarningSpec,
707 MoveToLine(Loc,
true);
709 *
OS <<
"#pragma warning(";
710 switch(WarningSpec) {
711 case PWS_Default: *
OS <<
"default";
break;
712 case PWS_Disable: *
OS <<
"disable";
break;
713 case PWS_Error: *
OS <<
"error";
break;
714 case PWS_Once: *
OS <<
"once";
break;
715 case PWS_Suppress: *
OS <<
"suppress";
break;
716 case PWS_Level1: *
OS <<
'1';
break;
717 case PWS_Level2: *
OS <<
'2';
break;
718 case PWS_Level3: *
OS <<
'3';
break;
719 case PWS_Level4: *
OS <<
'4';
break;
723 for (ArrayRef<int>::iterator I = Ids.begin(), E = Ids.end(); I != E; ++I)
726 setEmittedDirectiveOnThisLine();
729void PrintPPOutputPPCallbacks::PragmaWarningPush(SourceLocation Loc,
731 MoveToLine(Loc,
true);
732 *
OS <<
"#pragma warning(push";
736 setEmittedDirectiveOnThisLine();
739void PrintPPOutputPPCallbacks::PragmaWarningPop(SourceLocation Loc) {
740 MoveToLine(Loc,
true);
741 *
OS <<
"#pragma warning(pop)";
742 setEmittedDirectiveOnThisLine();
745void PrintPPOutputPPCallbacks::PragmaExecCharsetPush(SourceLocation Loc,
747 MoveToLine(Loc,
true);
748 *
OS <<
"#pragma character_execution_set(push";
752 setEmittedDirectiveOnThisLine();
755void PrintPPOutputPPCallbacks::PragmaExecCharsetPop(SourceLocation Loc) {
756 MoveToLine(Loc,
true);
757 *
OS <<
"#pragma character_execution_set(pop)";
758 setEmittedDirectiveOnThisLine();
761void PrintPPOutputPPCallbacks::
762PragmaAssumeNonNullBegin(SourceLocation Loc) {
763 MoveToLine(Loc,
true);
764 *
OS <<
"#pragma clang assume_nonnull begin";
765 setEmittedDirectiveOnThisLine();
768void PrintPPOutputPPCallbacks::
769PragmaAssumeNonNullEnd(SourceLocation Loc) {
770 MoveToLine(Loc,
true);
771 *
OS <<
"#pragma clang assume_nonnull end";
772 setEmittedDirectiveOnThisLine();
775void PrintPPOutputPPCallbacks::PragmaSetPPState(SourceLocation Loc,
776 IdentifierInfo *MacroName,
777 std::uint64_t
Value) {
778 MoveToLine(Loc,
true);
779 *
OS <<
"#pragma clang __set_pp_state " << MacroName->
getName() <<
" "
781 setEmittedDirectiveOnThisLine();
784void PrintPPOutputPPCallbacks::HandleWhitespaceBeforeTok(
const Token &
Tok,
786 bool RequireSameLine) {
789 if (
Tok.
is(tok::eof) ||
791 !
Tok.
is(tok::annot_module_begin) && !
Tok.
is(tok::annot_module_end) &&
792 !
Tok.
is(tok::annot_repl_input_end) && !
Tok.
is(tok::annot_embed) &&
793 !
Tok.
is(tok::annot_module_name)))
797 if ((!RequireSameLine || EmittedDirectiveOnThisLine) &&
798 MoveToLine(
Tok, EmittedDirectiveOnThisLine)) {
799 if (MinimizeWhitespace) {
801 if (
Tok.
is(tok::hash))
821 if (ColNo <= 1 &&
Tok.
is(tok::hash))
825 for (; ColNo > 1; --ColNo)
836 ((EmittedTokensOnThisLine || EmittedDirectiveOnThisLine) &&
837 AvoidConcat(PrevPrevTok, PrevTok,
Tok)))
841 PrevPrevTok = PrevTok;
845void PrintPPOutputPPCallbacks::HandleNewlinesInToken(
const char *TokStr,
847 unsigned NumNewlines = 0;
848 for (; Len; --Len, ++TokStr) {
849 if (*TokStr !=
'\n' &&
857 (TokStr[1] ==
'\n' || TokStr[1] ==
'\r') &&
858 TokStr[0] != TokStr[1]) {
864 if (NumNewlines == 0)
return;
866 CurLine += NumNewlines;
871struct UnknownPragmaHandler :
public PragmaHandler {
873 PrintPPOutputPPCallbacks *Callbacks;
876 bool ShouldExpandTokens;
878 UnknownPragmaHandler(
const char *prefix, PrintPPOutputPPCallbacks *callbacks,
879 bool RequireTokenExpansion)
880 : Prefix(prefix), Callbacks(callbacks),
881 ShouldExpandTokens(RequireTokenExpansion) {}
882 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
883 Token &PragmaTok)
override {
886 Callbacks->MoveToLine(PragmaTok.
getLocation(),
true);
887 Callbacks->OS->write(Prefix, strlen(Prefix));
888 Callbacks->setEmittedTokensOnThisLine();
890 if (ShouldExpandTokens) {
893 auto Toks = std::make_unique<Token[]>(1);
895 PP.EnterTokenStream(std::move(Toks), 1,
903 while (PragmaTok.
isNot(tok::eod)) {
904 Callbacks->HandleWhitespaceBeforeTok(PragmaTok,
IsFirst,
908 Callbacks->OS->write(&TokSpell[0], TokSpell.size());
909 Callbacks->setEmittedTokensOnThisLine();
911 if (ShouldExpandTokens)
916 Callbacks->setEmittedDirectiveOnThisLine();
923 PrintPPOutputPPCallbacks *Callbacks) {
924 bool DropComments = PP.
getLangOpts().TraditionalCPP &&
927 bool IsStartOfLine =
false;
928 bool IsCXXModuleDirective =
false;
938 IsStartOfLine = IsStartOfLine ||
Tok.isAtStartOfLine();
940 Callbacks->HandleWhitespaceBeforeTok(
Tok,
false,
943 if (DropComments &&
Tok.is(tok::comment)) {
949 }
else if (
Tok.is(tok::annot_repl_input_end)) {
951 }
else if (
Tok.is(tok::eod)) {
958 IsStartOfLine =
true;
960 }
else if (
Tok.is(tok::annot_module_include)) {
964 IsStartOfLine =
true;
966 }
else if (
Tok.is(tok::annot_module_begin)) {
973 Callbacks->BeginModule(
974 reinterpret_cast<Module *
>(
Tok.getAnnotationValue()));
976 IsStartOfLine =
true;
978 }
else if (
Tok.is(tok::annot_module_end)) {
979 Callbacks->EndModule(
980 reinterpret_cast<Module *
>(
Tok.getAnnotationValue()));
982 IsStartOfLine =
true;
984 }
else if (
Tok.is(tok::annot_header_unit)) {
992 *Callbacks->OS <<
'"';
993 Callbacks->OS->write_escaped(Name);
994 *Callbacks->OS <<
'"';
995 }
else if (
Tok.is(tok::annot_embed)) {
1000 assert(Callbacks->expandEmbedContents() &&
1001 "did not expect an embed annotation");
1007 bool PrintComma =
false;
1008 for (
unsigned char Byte :
Data->BinaryData.bytes()) {
1010 *Callbacks->OS <<
", ";
1011 *Callbacks->OS <<
static_cast<int>(Byte);
1014 }
else if (
Tok.is(tok::annot_module_name)) {
1016 *Callbacks->OS << NameLoc->str();
1017 }
else if (
Tok.isAnnotation()) {
1022 }
else if (PP.
getLangOpts().CPlusPlusModules &&
Tok.is(tok::kw_import) &&
1023 !Callbacks->GetPrevToken().is(tok::at)) {
1024 assert(!IsCXXModuleDirective &&
"Is an import directive being printed?");
1025 IsCXXModuleDirective =
true;
1026 IsStartOfLine =
false;
1028 tok::pp___preprocessed_import);
1031 }
else if (PP.
getLangOpts().CPlusPlusModules &&
Tok.is(tok::kw_module)) {
1032 assert(!IsCXXModuleDirective &&
"Is an module directive being printed?");
1033 IsCXXModuleDirective =
true;
1034 IsStartOfLine =
false;
1036 tok::pp___preprocessed_module);
1039 }
else if (PP.
getLangOpts().CPlusPlusModules && IsCXXModuleDirective &&
1040 Tok.is(tok::semi)) {
1041 IsCXXModuleDirective =
false;
1042 IsStartOfLine =
true;
1043 *Callbacks->OS <<
';';
1047 *Callbacks->OS << II->getName();
1048 }
else if (
Tok.isLiteral() && !
Tok.needsCleaning() &&
1049 Tok.getLiteralData()) {
1050 Callbacks->OS->write(
Tok.getLiteralData(),
Tok.getLength());
1051 }
else if (
Tok.getLength() < std::size(Buffer)) {
1052 const char *TokPtr = Buffer;
1054 Callbacks->OS->write(TokPtr, Len);
1061 if (
Tok.getKind() == tok::comment ||
Tok.getKind() == tok::unknown)
1062 Callbacks->HandleNewlinesInToken(TokPtr, Len);
1063 if (
Tok.is(tok::comment) && Len >= 2 && TokPtr[0] ==
'/' &&
1067 Callbacks->setEmittedDirectiveOnThisLine();
1071 Callbacks->OS->write(S.data(), S.size());
1075 if (
Tok.getKind() == tok::comment ||
Tok.getKind() == tok::unknown)
1076 Callbacks->HandleNewlinesInToken(S.data(), S.size());
1077 if (
Tok.is(tok::comment) && S.size() >= 2 && S[0] ==
'/' && S[1] ==
'/') {
1080 Callbacks->setEmittedDirectiveOnThisLine();
1083 Callbacks->setEmittedTokensOnThisLine();
1084 IsStartOfLine =
false;
1086 if (
Tok.is(tok::eof) ||
Tok.is(tok::annot_repl_input_end))
1091 for (
unsigned I = 0,
Skip = Callbacks->GetNumToksToSkip(); I <
Skip; ++I)
1093 Callbacks->ResetSkipToks();
1099 return LHS->first->getName().compare(RHS->first->getName());
1113 for (
const auto &M : PP.
macros()) {
1114 auto *MD = M.second.getLatest();
1115 if (MD && MD->isDefined())
1118 llvm::array_pod_sort(MacrosByID.begin(), MacrosByID.end(),
MacroIDCompare);
1120 for (
unsigned i = 0, e = MacrosByID.size(); i != e; ++i) {
1136 assert(Opts.
ShowMacros &&
"Not yet implemented!");
1145 PrintPPOutputPPCallbacks *Callbacks =
new PrintPPOutputPPCallbacks(
1154 std::unique_ptr<UnknownPragmaHandler> MicrosoftExtHandler(
1155 new UnknownPragmaHandler(
1156 "#pragma", Callbacks,
1159 std::unique_ptr<UnknownPragmaHandler> GCCHandler(
new UnknownPragmaHandler(
1160 "#pragma GCC", Callbacks,
1163 std::unique_ptr<UnknownPragmaHandler> ClangHandler(
new UnknownPragmaHandler(
1164 "#pragma clang", Callbacks,
1176 std::unique_ptr<UnknownPragmaHandler> OpenMPHandler(
1177 new UnknownPragmaHandler(
"#pragma omp", Callbacks,
1195 if (
Tok.is(tok::eof) || !
Tok.getLocation().isFileID())
Defines the Diagnostic-related interfaces.
llvm::MachO::FileType FileType
Defines the clang::MacroInfo and clang::MacroDirective classes.
Defines the PPCallbacks interface.
Defines the clang::Preprocessor interface.
static void PrintMacroDefinition(const IdentifierInfo *II, const MacroInfo &MI, Preprocessor &PP, raw_ostream *OS)
PrintMacroDefinition - Print a macro definition in a form that will be properly accepted back as a de...
std::pair< const IdentifierInfo *, MacroInfo * > id_macro_pair
static void DoPrintMacros(Preprocessor &PP, raw_ostream *OS)
static int MacroIDCompare(const id_macro_pair *LHS, const id_macro_pair *RHS)
static void PrintPreprocessedTokens(Preprocessor &PP, Token &Tok, PrintPPOutputPPCallbacks *Callbacks)
static void outputPrintable(raw_ostream *OS, StringRef Str)
Defines the SourceManager interface.
One of these records is kept for each identifier that is lexed.
tok::PPKeywordKind getPPKeywordID() const
Return the preprocessor keyword ID for this identifier.
StringRef getName() const
Return the actual identifier string.
MacroInfo * getMacroInfo() const
Get the MacroInfo that should be used for this definition.
const MacroInfo * getMacroInfo() const
Encapsulates the data about a macro definition (e.g.
bool isUsed() const
Return false if this macro is defined in the main file and has not yet been used.
bool isFunctionLike() const
const_tokens_iterator tokens_begin() const
param_iterator param_begin() const
bool isBuiltinMacro() const
Return true if this macro requires processing before expansion.
IdentifierInfo *const * param_iterator
Parameters - The list of parameters for a function-like macro.
SourceLocation getDefinitionLoc() const
Return the location that the macro was defined at.
bool tokens_empty() const
param_iterator param_end() const
ArrayRef< Token > tokens() const
bool isGNUVarargs() const
Describes a module or submodule.
std::string getFullModuleName(bool AllowStringLiterals=false) const
Retrieve the full name of this module, including the path from its top-level module.
This interface provides a way to observe the actions of the preprocessor as it does its thing.
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 ShowComments
Show comments.
unsigned ShowEmbedDirectives
Print embeds, etc. within preprocessed.
unsigned ShowLineMarkers
Show #line markers.
unsigned DirectivesOnly
Process directives but do not expand macros.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
bool isPragmaSetPPStateMacro(IdentifierInfo *II)
Check whether this is a macro name that can be used as an argument to 'pragma clang __set_pp_state'.
void IgnorePragmas()
Install empty handlers for all pragmas (making them ignored).
llvm::iterator_range< macro_iterator > macros(bool IncludeExternalMacros=true) const
void Lex(Token &Result)
Lex the next token for this preprocessor.
void addPPCallbacks(std::unique_ptr< PPCallbacks > C)
void EnterMainSourceFile()
Enter the specified FileID as the main source file, which implicitly adds the builtin defines etc.
SourceManager & getSourceManager() const
bool getCommentRetentionState() const
void SetMacroExpansionOnlyInDirectives()
Disables macro expansion everywhere except for preprocessor directives.
void LexUnexpandedToken(Token &Result)
Just like Lex, but disables macro expansion of identifier tokens.
void AddPragmaHandler(StringRef Namespace, PragmaHandler *Handler)
Add the specified pragma handler to this preprocessor.
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.
Represents an unpacked "presumed" location which can be presented to the user.
const char * getFilename() const
Return the presumed filename of this location.
unsigned getLine() const
Return the presumed line number of this location.
bool isInvalid() const
Return true if this object is invalid or uninitialized.
SourceLocation getIncludeLoc() const
Return the presumed include location of this location.
bool isValid() const
Return true if this is a valid SourceLocation object.
This class handles loading and caching of source files into memory.
bool isInPredefinedFile(SourceLocation Loc) const
Returns whether Loc is located in a built-in or command line source.
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
unsigned getExpansionColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const
Token - This structure provides full information about a lexed token.
IdentifierInfo * getIdentifierInfo() const
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
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)) {....
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
bool hasLeadingSpace() const
Return true if this token has whitespace before it.
bool isNot(tok::TokenKind K) const
bool isAnnotation() const
Return true if this is any of tok::annot_* kind tokens.
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
bool isSystem(CharacteristicKind CK)
Determine whether a file / directory characteristic is for system code.
Severity
Enum values that allow the client to map NOTEs, WARNINGs, and EXTENSIONs to either Ignore (nothing),...
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
const char * getPPKeywordSpelling(PPKeywordKind Kind) LLVM_READNONE
Returns the spelling of preprocessor keywords, such as "else".
Top level wrappers for InstallAPI frontend operations.
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
LLVM_READONLY bool isPrintable(unsigned char c)
Return true if this character is an ASCII printable character; that is, a character that should take ...
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
const FunctionProtoType * T
void DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream *OS, const PreprocessorOutputOptions &Opts)
DoPrintPreprocessedInput - Implement -E mode.
Helper class to shuttle information about embed directives from the preprocessor to the parser throug...
std::optional< PPEmbedParameterIfEmpty > MaybeIfEmptyParam
std::optional< PPEmbedParameterOffset > MaybeOffsetParam
std::optional< PPEmbedParameterLimit > MaybeLimitParam
std::optional< PPEmbedParameterSuffix > MaybeSuffixParam
std::optional< PPEmbedParameterPrefix > MaybePrefixParam