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"
35 *OS <<
"#define " << II.
getName();
41 for (; AI+1 != E; ++AI) {
42 *OS << (*AI)->getName();
47 if ((*AI)->getName() ==
"__VA_ARGS__")
50 *OS << (*AI)->getName();
65 for (
const auto &
T : MI.
tokens()) {
66 if (
T.hasLeadingSpace())
78class PrintPPOutputPPCallbacks :
public PPCallbacks {
81 TokenConcatenation ConcatInfo;
87 bool EmittedTokensOnThisLine;
88 bool EmittedDirectiveOnThisLine;
90 SmallString<512> CurFilename;
92 bool DisableLineMarkers;
94 bool DumpIncludeDirectives;
95 bool DumpEmbedDirectives;
96 bool UseLineDirectives;
97 bool IsFirstFileEntered;
98 bool MinimizeWhitespace;
100 bool KeepSystemIncludes;
102 std::unique_ptr<llvm::raw_null_ostream> NullOS;
103 unsigned NumToksToSkip;
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) {
122 CurFilename +=
"<uninit>";
123 EmittedTokensOnThisLine =
false;
124 EmittedDirectiveOnThisLine =
false;
127 IsFirstFileEntered =
false;
128 if (KeepSystemIncludes)
129 NullOS = std::make_unique<llvm::raw_null_ostream>();
131 PrevTok.startToken();
132 PrevPrevTok.startToken();
137 bool expandEmbedContents()
const {
return !DumpEmbedDirectives; }
139 bool isMinimizeWhitespace()
const {
return MinimizeWhitespace; }
141 void setEmittedTokensOnThisLine() { EmittedTokensOnThisLine =
true; }
142 bool hasEmittedTokensOnThisLine()
const {
return EmittedTokensOnThisLine; }
144 void setEmittedDirectiveOnThisLine() { EmittedDirectiveOnThisLine =
true; }
145 bool hasEmittedDirectiveOnThisLine()
const {
146 return EmittedDirectiveOnThisLine;
154 void startNewLineIfNeeded();
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,
164 CharSourceRange FilenameRange,
166 StringRef RelativePath,
const Module *SuggestedModule,
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,
177 void PragmaWarning(SourceLocation Loc, PragmaWarningSpecifier WarningSpec,
178 ArrayRef<int> Ids)
override;
179 void PragmaWarningPush(SourceLocation Loc,
int Level)
override;
180 void PragmaWarningPop(SourceLocation Loc)
override;
181 void PragmaExecCharsetPush(SourceLocation Loc, StringRef Str)
override;
182 void PragmaExecCharsetPop(SourceLocation Loc)
override;
183 void PragmaAssumeNonNullBegin(SourceLocation Loc)
override;
184 void PragmaAssumeNonNullEnd(SourceLocation Loc)
override;
193 void HandleWhitespaceBeforeTok(
const Token &
Tok,
bool RequireSpace,
194 bool RequireSameLine);
208 bool MoveToLine(
const Token &
Tok,
bool RequireStartOfLine) {
213 return MoveToLine(TargetLine, RequireStartOfLine) || IsFirstInFile;
218 bool MoveToLine(SourceLocation Loc,
bool RequireStartOfLine) {
219 PresumedLoc PLoc = SM.getPresumedLoc(Loc);
221 return MoveToLine(TargetLine, RequireStartOfLine);
223 bool MoveToLine(
unsigned LineNo,
bool RequireStartOfLine);
225 bool AvoidConcat(
const Token &PrevPrevTok,
const Token &PrevTok,
227 return ConcatInfo.AvoidConcat(PrevPrevTok, PrevTok,
Tok);
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);
235 void MacroDefined(
const Token &MacroNameTok,
236 const MacroDirective *MD)
override;
239 void MacroUndefined(
const Token &MacroNameTok,
240 const MacroDefinition &MD,
241 const MacroDirective *Undef)
override;
243 void BeginModule(
const Module *M);
244 void EndModule(
const Module *M);
246 unsigned GetNumToksToSkip()
const {
return NumToksToSkip; }
247 void ResetSkipToks() { NumToksToSkip = 0; }
249 const Token &GetPrevToken()
const {
return PrevTok; }
253void PrintPPOutputPPCallbacks::WriteLineInfo(
unsigned LineNo,
256 startNewLineIfNeeded();
259 if (UseLineDirectives) {
260 *
OS <<
"#line" <<
' ' << LineNo <<
' ' <<
'"';
261 OS->write_escaped(CurFilename);
264 *
OS <<
'#' <<
' ' << LineNo <<
' ' <<
'"';
265 OS->write_escaped(CurFilename);
274 OS->write(
" 3 4", 4);
283bool PrintPPOutputPPCallbacks::MoveToLine(
unsigned LineNo,
284 bool RequireStartOfLine) {
288 bool StartedNewLine =
false;
289 if ((RequireStartOfLine && EmittedTokensOnThisLine) ||
290 EmittedDirectiveOnThisLine) {
292 StartedNewLine =
true;
294 EmittedTokensOnThisLine =
false;
295 EmittedDirectiveOnThisLine =
false;
300 if (CurLine == LineNo) {
302 }
else if (MinimizeWhitespace && DisableLineMarkers) {
304 }
else if (!StartedNewLine && LineNo - CurLine == 1) {
309 StartedNewLine =
true;
310 }
else if (!DisableLineMarkers) {
311 if (LineNo - CurLine <= 8) {
312 const char *NewLines =
"\n\n\n\n\n\n\n\n";
313 OS->write(NewLines, LineNo - CurLine);
316 WriteLineInfo(LineNo,
nullptr, 0);
318 StartedNewLine =
true;
319 }
else if (EmittedTokensOnThisLine) {
323 StartedNewLine =
true;
326 if (StartedNewLine) {
327 EmittedTokensOnThisLine =
false;
328 EmittedDirectiveOnThisLine =
false;
332 return StartedNewLine;
335void PrintPPOutputPPCallbacks::startNewLineIfNeeded() {
336 if (EmittedTokensOnThisLine || EmittedDirectiveOnThisLine) {
338 EmittedTokensOnThisLine =
false;
339 EmittedDirectiveOnThisLine =
false;
346void PrintPPOutputPPCallbacks::FileChanged(SourceLocation Loc,
347 FileChangeReason Reason,
352 SourceManager &SourceMgr =
SM;
358 unsigned NewLine = UserLoc.
getLine();
363 MoveToLine(IncludeLoc,
false);
383 if (DisableLineMarkers) {
384 if (!MinimizeWhitespace)
385 startNewLineIfNeeded();
390 WriteLineInfo(CurLine);
399 IsFirstFileEntered =
true;
405 WriteLineInfo(CurLine,
" 1", 2);
408 WriteLineInfo(CurLine,
" 2", 2);
412 WriteLineInfo(CurLine);
417void PrintPPOutputPPCallbacks::EmbedDirective(
418 SourceLocation HashLoc, StringRef
FileName,
bool IsAngled,
420 if (!DumpEmbedDirectives)
433 MoveToLine(HashLoc,
true);
434 *
OS <<
"#embed " << (IsAngled ?
'<' :
'"') <<
FileName
435 << (IsAngled ?
'>' :
'"');
437 auto PrintToks = [&](llvm::ArrayRef<Token> Toks) {
438 SmallString<128> SpellingBuffer;
439 for (
const Token &
T : Toks) {
440 if (
T.hasLeadingSpace())
445 bool SkipAnnotToks =
true;
454 SkipAnnotToks =
false;
481 *
OS <<
" /* clang -E -dE */";
482 setEmittedDirectiveOnThisLine();
485void PrintPPOutputPPCallbacks::InclusionDirective(
486 SourceLocation HashLoc,
const Token &IncludeTok, StringRef
FileName,
488 StringRef SearchPath, StringRef RelativePath,
const Module *SuggestedModule,
493 MoveToLine(HashLoc,
true);
497 << (IsAngled ?
'<' :
'"') <<
FileName << (IsAngled ?
'>' :
'"')
499 << (DumpIncludeDirectives ?
"-dI" :
"-fkeep-system-includes")
501 setEmittedDirectiveOnThisLine();
505 if (ModuleImported) {
507 case tok::pp_include:
509 case tok::pp_include_next:
510 MoveToLine(HashLoc,
true);
511 *
OS <<
"#pragma clang module import "
513 <<
" /* clang -E: implicit import for "
515 << (IsAngled ?
'<' :
'"') <<
FileName << (IsAngled ?
'>' :
'"')
517 setEmittedDirectiveOnThisLine();
520 case tok::pp___include_macros:
529 llvm_unreachable(
"unknown include directive kind");
536void PrintPPOutputPPCallbacks::BeginModule(
const Module *M) {
537 startNewLineIfNeeded();
539 setEmittedDirectiveOnThisLine();
543void PrintPPOutputPPCallbacks::EndModule(
const Module *M) {
544 startNewLineIfNeeded();
546 setEmittedDirectiveOnThisLine();
551void PrintPPOutputPPCallbacks::Ident(SourceLocation Loc, StringRef S) {
552 MoveToLine(Loc,
true);
554 OS->write(
"#ident ", strlen(
"#ident "));
555 OS->write(S.begin(), S.size());
556 setEmittedTokensOnThisLine();
560void PrintPPOutputPPCallbacks::MacroDefined(
const Token &MacroNameTok,
561 const MacroDirective *MD) {
565 if ((!DumpDefines && !DirectivesOnly) ||
571 if (DirectivesOnly && !MI->
isUsed()) {
573 if (
SM.isInPredefinedFile(DefLoc))
576 MoveToLine(DefLoc,
true);
578 setEmittedDirectiveOnThisLine();
581void PrintPPOutputPPCallbacks::MacroUndefined(
const Token &MacroNameTok,
582 const MacroDefinition &MD,
583 const MacroDirective *Undef) {
586 if (!DumpDefines && !DirectivesOnly)
591 setEmittedDirectiveOnThisLine();
595 for (
unsigned char Char : Str) {
596 if (
isPrintable(Char) && Char !=
'\\' && Char !=
'"')
600 << (char)(
'0' + ((Char >> 6) & 7))
601 << (char)(
'0' + ((Char >> 3) & 7))
602 << (char)(
'0' + ((Char >> 0) & 7));
606void PrintPPOutputPPCallbacks::PragmaMessage(SourceLocation Loc,
608 PragmaMessageKind Kind,
610 MoveToLine(Loc,
true);
628 if (Kind == PMK_Message)
630 setEmittedDirectiveOnThisLine();
633void PrintPPOutputPPCallbacks::PragmaDebug(SourceLocation Loc,
634 StringRef DebugType) {
635 MoveToLine(Loc,
true);
637 *
OS <<
"#pragma clang __debug ";
640 setEmittedDirectiveOnThisLine();
643void PrintPPOutputPPCallbacks::
644PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace) {
645 MoveToLine(Loc,
true);
646 *
OS <<
"#pragma " <<
Namespace <<
" diagnostic push";
647 setEmittedDirectiveOnThisLine();
650void PrintPPOutputPPCallbacks::
651PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace) {
652 MoveToLine(Loc,
true);
653 *
OS <<
"#pragma " <<
Namespace <<
" diagnostic pop";
654 setEmittedDirectiveOnThisLine();
657void PrintPPOutputPPCallbacks::PragmaDiagnostic(SourceLocation Loc,
661 MoveToLine(Loc,
true);
664 case diag::Severity::Remark:
667 case diag::Severity::Warning:
670 case diag::Severity::Error:
673 case diag::Severity::Ignored:
676 case diag::Severity::Fatal:
680 *
OS <<
" \"" << Str <<
'"';
681 setEmittedDirectiveOnThisLine();
684void PrintPPOutputPPCallbacks::PragmaWarning(SourceLocation Loc,
685 PragmaWarningSpecifier WarningSpec,
687 MoveToLine(Loc,
true);
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;
703 for (ArrayRef<int>::iterator I = Ids.begin(), E = Ids.end(); I != E; ++I)
706 setEmittedDirectiveOnThisLine();
709void PrintPPOutputPPCallbacks::PragmaWarningPush(SourceLocation Loc,
711 MoveToLine(Loc,
true);
712 *
OS <<
"#pragma warning(push";
716 setEmittedDirectiveOnThisLine();
719void PrintPPOutputPPCallbacks::PragmaWarningPop(SourceLocation Loc) {
720 MoveToLine(Loc,
true);
721 *
OS <<
"#pragma warning(pop)";
722 setEmittedDirectiveOnThisLine();
725void PrintPPOutputPPCallbacks::PragmaExecCharsetPush(SourceLocation Loc,
727 MoveToLine(Loc,
true);
728 *
OS <<
"#pragma character_execution_set(push";
732 setEmittedDirectiveOnThisLine();
735void PrintPPOutputPPCallbacks::PragmaExecCharsetPop(SourceLocation Loc) {
736 MoveToLine(Loc,
true);
737 *
OS <<
"#pragma character_execution_set(pop)";
738 setEmittedDirectiveOnThisLine();
741void PrintPPOutputPPCallbacks::
742PragmaAssumeNonNullBegin(SourceLocation Loc) {
743 MoveToLine(Loc,
true);
744 *
OS <<
"#pragma clang assume_nonnull begin";
745 setEmittedDirectiveOnThisLine();
748void PrintPPOutputPPCallbacks::
749PragmaAssumeNonNullEnd(SourceLocation Loc) {
750 MoveToLine(Loc,
true);
751 *
OS <<
"#pragma clang assume_nonnull end";
752 setEmittedDirectiveOnThisLine();
755void PrintPPOutputPPCallbacks::HandleWhitespaceBeforeTok(
const Token &
Tok,
757 bool RequireSameLine) {
760 if (
Tok.
is(tok::eof) ||
762 !
Tok.
is(tok::annot_module_begin) && !
Tok.
is(tok::annot_module_end) &&
763 !
Tok.
is(tok::annot_repl_input_end) && !
Tok.
is(tok::annot_embed) &&
764 !
Tok.
is(tok::annot_module_name)))
768 if ((!RequireSameLine || EmittedDirectiveOnThisLine) &&
769 MoveToLine(
Tok, EmittedDirectiveOnThisLine)) {
770 if (MinimizeWhitespace) {
772 if (
Tok.
is(tok::hash))
792 if (ColNo <= 1 &&
Tok.
is(tok::hash))
796 for (; ColNo > 1; --ColNo)
807 ((EmittedTokensOnThisLine || EmittedDirectiveOnThisLine) &&
808 AvoidConcat(PrevPrevTok, PrevTok,
Tok)))
812 PrevPrevTok = PrevTok;
816void PrintPPOutputPPCallbacks::HandleNewlinesInToken(
const char *TokStr,
818 unsigned NumNewlines = 0;
819 for (; Len; --Len, ++TokStr) {
820 if (*TokStr !=
'\n' &&
828 (TokStr[1] ==
'\n' || TokStr[1] ==
'\r') &&
829 TokStr[0] != TokStr[1]) {
835 if (NumNewlines == 0)
return;
837 CurLine += NumNewlines;
842struct UnknownPragmaHandler :
public PragmaHandler {
844 PrintPPOutputPPCallbacks *Callbacks;
847 bool ShouldExpandTokens;
849 UnknownPragmaHandler(
const char *prefix, PrintPPOutputPPCallbacks *callbacks,
850 bool RequireTokenExpansion)
851 : Prefix(prefix), Callbacks(callbacks),
852 ShouldExpandTokens(RequireTokenExpansion) {}
853 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
854 Token &PragmaTok)
override {
857 Callbacks->MoveToLine(PragmaTok.
getLocation(),
true);
858 Callbacks->OS->write(Prefix, strlen(Prefix));
859 Callbacks->setEmittedTokensOnThisLine();
861 if (ShouldExpandTokens) {
864 auto Toks = std::make_unique<Token[]>(1);
866 PP.EnterTokenStream(std::move(Toks), 1,
874 while (PragmaTok.
isNot(tok::eod)) {
875 Callbacks->HandleWhitespaceBeforeTok(PragmaTok,
IsFirst,
879 Callbacks->OS->write(&TokSpell[0], TokSpell.size());
880 Callbacks->setEmittedTokensOnThisLine();
882 if (ShouldExpandTokens)
887 Callbacks->setEmittedDirectiveOnThisLine();
894 PrintPPOutputPPCallbacks *Callbacks) {
895 bool DropComments = PP.
getLangOpts().TraditionalCPP &&
898 bool IsStartOfLine =
false;
899 bool IsCXXModuleDirective =
false;
909 IsStartOfLine = IsStartOfLine ||
Tok.isAtStartOfLine();
911 Callbacks->HandleWhitespaceBeforeTok(
Tok,
false,
914 if (DropComments &&
Tok.is(tok::comment)) {
920 }
else if (
Tok.is(tok::annot_repl_input_end)) {
922 }
else if (
Tok.is(tok::eod)) {
929 IsStartOfLine =
true;
931 }
else if (
Tok.is(tok::annot_module_include)) {
935 IsStartOfLine =
true;
937 }
else if (
Tok.is(tok::annot_module_begin)) {
944 Callbacks->BeginModule(
945 reinterpret_cast<Module *
>(
Tok.getAnnotationValue()));
947 IsStartOfLine =
true;
949 }
else if (
Tok.is(tok::annot_module_end)) {
950 Callbacks->EndModule(
951 reinterpret_cast<Module *
>(
Tok.getAnnotationValue()));
953 IsStartOfLine =
true;
955 }
else if (
Tok.is(tok::annot_header_unit)) {
963 *Callbacks->OS <<
'"';
964 Callbacks->OS->write_escaped(Name);
965 *Callbacks->OS <<
'"';
966 }
else if (
Tok.is(tok::annot_embed)) {
971 assert(Callbacks->expandEmbedContents() &&
972 "did not expect an embed annotation");
978 bool PrintComma =
false;
979 for (
unsigned char Byte :
Data->BinaryData.bytes()) {
981 *Callbacks->OS <<
", ";
982 *Callbacks->OS <<
static_cast<int>(Byte);
985 }
else if (
Tok.is(tok::annot_module_name)) {
987 *Callbacks->OS << NameLoc->str();
988 }
else if (
Tok.isAnnotation()) {
993 }
else if (PP.
getLangOpts().CPlusPlusModules &&
Tok.is(tok::kw_import) &&
994 !Callbacks->GetPrevToken().is(tok::at)) {
995 assert(!IsCXXModuleDirective &&
"Is an import directive being printed?");
996 IsCXXModuleDirective =
true;
997 IsStartOfLine =
false;
999 tok::pp___preprocessed_import);
1002 }
else if (PP.
getLangOpts().CPlusPlusModules &&
Tok.is(tok::kw_module)) {
1003 assert(!IsCXXModuleDirective &&
"Is an module directive being printed?");
1004 IsCXXModuleDirective =
true;
1005 IsStartOfLine =
false;
1007 tok::pp___preprocessed_module);
1010 }
else if (PP.
getLangOpts().CPlusPlusModules && IsCXXModuleDirective &&
1011 Tok.is(tok::semi)) {
1012 IsCXXModuleDirective =
false;
1013 IsStartOfLine =
true;
1014 *Callbacks->OS <<
';';
1018 *Callbacks->OS << II->getName();
1019 }
else if (
Tok.isLiteral() && !
Tok.needsCleaning() &&
1020 Tok.getLiteralData()) {
1021 Callbacks->OS->write(
Tok.getLiteralData(),
Tok.getLength());
1022 }
else if (
Tok.getLength() < std::size(Buffer)) {
1023 const char *TokPtr = Buffer;
1025 Callbacks->OS->write(TokPtr, Len);
1032 if (
Tok.getKind() == tok::comment ||
Tok.getKind() == tok::unknown)
1033 Callbacks->HandleNewlinesInToken(TokPtr, Len);
1034 if (
Tok.is(tok::comment) && Len >= 2 && TokPtr[0] ==
'/' &&
1038 Callbacks->setEmittedDirectiveOnThisLine();
1042 Callbacks->OS->write(S.data(), S.size());
1046 if (
Tok.getKind() == tok::comment ||
Tok.getKind() == tok::unknown)
1047 Callbacks->HandleNewlinesInToken(S.data(), S.size());
1048 if (
Tok.is(tok::comment) && S.size() >= 2 && S[0] ==
'/' && S[1] ==
'/') {
1051 Callbacks->setEmittedDirectiveOnThisLine();
1054 Callbacks->setEmittedTokensOnThisLine();
1055 IsStartOfLine =
false;
1057 if (
Tok.is(tok::eof) ||
Tok.is(tok::annot_repl_input_end))
1062 for (
unsigned I = 0,
Skip = Callbacks->GetNumToksToSkip(); I <
Skip; ++I)
1064 Callbacks->ResetSkipToks();
1070 return LHS->first->getName().compare(RHS->first->getName());
1086 auto *MD = I->second.getLatest();
1087 if (MD && MD->isDefined())
1090 llvm::array_pod_sort(MacrosByID.begin(), MacrosByID.end(),
MacroIDCompare);
1092 for (
unsigned i = 0, e = MacrosByID.size(); i != e; ++i) {
1108 assert(Opts.
ShowMacros &&
"Not yet implemented!");
1117 PrintPPOutputPPCallbacks *Callbacks =
new PrintPPOutputPPCallbacks(
1126 std::unique_ptr<UnknownPragmaHandler> MicrosoftExtHandler(
1127 new UnknownPragmaHandler(
1128 "#pragma", Callbacks,
1131 std::unique_ptr<UnknownPragmaHandler> GCCHandler(
new UnknownPragmaHandler(
1132 "#pragma GCC", Callbacks,
1135 std::unique_ptr<UnknownPragmaHandler> ClangHandler(
new UnknownPragmaHandler(
1136 "#pragma clang", Callbacks,
1148 std::unique_ptr<UnknownPragmaHandler> OpenMPHandler(
1149 new UnknownPragmaHandler(
"#pragma omp", Callbacks,
1167 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.
std::pair< const IdentifierInfo *, MacroInfo * > id_macro_pair
static void DoPrintMacros(Preprocessor &PP, raw_ostream *OS)
static void PrintMacroDefinition(const IdentifierInfo &II, const MacroInfo &MI, Preprocessor &PP, raw_ostream *OS)
PrintMacroDefinition - Print a macro definition in a form that will be properly accepted back as a de...
static int MacroIDCompare(const id_macro_pair *LHS, const id_macro_pair *RHS)
static void PrintPreprocessedTokens(Preprocessor &PP, Token &Tok, PrintPPOutputPPCallbacks *Callbacks)
static void outputPrintable(raw_ostream *OS, StringRef Str)
Defines the SourceManager interface.
One of these records is kept for each identifier that is lexed.
tok::PPKeywordKind getPPKeywordID() const
Return the preprocessor keyword ID for this identifier.
StringRef getName() const
Return the actual identifier string.
MacroInfo * getMacroInfo() const
Get the MacroInfo that should be used for this definition.
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.
void IgnorePragmas()
Install empty handlers for all pragmas (making them ignored).
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.
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.
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
Token - This structure provides full information about a lexed token.
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".
The JSON file list parser is used to communicate input to InstallAPI.
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