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"
36 *OS <<
"#define " << II.
getName();
42 for (; AI+1 !=
E; ++AI) {
43 *OS << (*AI)->getName();
48 if ((*AI)->getName() ==
"__VA_ARGS__")
51 *OS << (*AI)->getName();
66 for (
const auto &
T : MI.
tokens()) {
67 if (
T.hasLeadingSpace())
79class PrintPPOutputPPCallbacks :
public PPCallbacks {
88 bool EmittedTokensOnThisLine;
89 bool EmittedDirectiveOnThisLine;
93 bool DisableLineMarkers;
95 bool DumpIncludeDirectives;
96 bool DumpEmbedDirectives;
97 bool UseLineDirectives;
98 bool IsFirstFileEntered;
99 bool MinimizeWhitespace;
101 bool KeepSystemIncludes;
103 std::unique_ptr<llvm::raw_null_ostream> NullOS;
104 unsigned NumToksToSkip;
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) {
123 CurFilename +=
"<uninit>";
124 EmittedTokensOnThisLine =
false;
125 EmittedDirectiveOnThisLine =
false;
128 IsFirstFileEntered =
false;
129 if (KeepSystemIncludes)
130 NullOS = std::make_unique<llvm::raw_null_ostream>();
138 bool expandEmbedContents()
const {
return !DumpEmbedDirectives; }
140 bool isMinimizeWhitespace()
const {
return MinimizeWhitespace; }
142 void setEmittedTokensOnThisLine() { EmittedTokensOnThisLine =
true; }
143 bool hasEmittedTokensOnThisLine()
const {
return EmittedTokensOnThisLine; }
145 void setEmittedDirectiveOnThisLine() { EmittedDirectiveOnThisLine =
true; }
146 bool hasEmittedDirectiveOnThisLine()
const {
147 return EmittedDirectiveOnThisLine;
155 void startNewLineIfNeeded();
167 StringRef RelativePath,
const Module *SuggestedModule,
172 PragmaMessageKind Kind, StringRef Str)
override;
194 void HandleWhitespaceBeforeTok(
const Token &Tok,
bool RequireSpace,
195 bool RequireSameLine);
209 bool MoveToLine(
const Token &Tok,
bool RequireStartOfLine) {
214 return MoveToLine(TargetLine, RequireStartOfLine) || IsFirstInFile;
222 return MoveToLine(TargetLine, RequireStartOfLine);
224 bool MoveToLine(
unsigned LineNo,
bool RequireStartOfLine);
226 bool AvoidConcat(
const Token &PrevPrevTok,
const Token &PrevTok,
228 return ConcatInfo.
AvoidConcat(PrevPrevTok, PrevTok, Tok);
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);
244 void BeginModule(
const Module *M);
245 void EndModule(
const Module *M);
247 unsigned GetNumToksToSkip()
const {
return NumToksToSkip; }
248 void ResetSkipToks() { NumToksToSkip = 0; }
252void PrintPPOutputPPCallbacks::WriteLineInfo(
unsigned LineNo,
255 startNewLineIfNeeded();
258 if (UseLineDirectives) {
259 *OS <<
"#line" <<
' ' << LineNo <<
' ' <<
'"';
260 OS->write_escaped(CurFilename);
263 *OS <<
'#' <<
' ' << LineNo <<
' ' <<
'"';
264 OS->write_escaped(CurFilename);
268 OS->write(Extra, ExtraLen);
273 OS->write(
" 3 4", 4);
282bool PrintPPOutputPPCallbacks::MoveToLine(
unsigned LineNo,
283 bool RequireStartOfLine) {
287 bool StartedNewLine =
false;
288 if ((RequireStartOfLine && EmittedTokensOnThisLine) ||
289 EmittedDirectiveOnThisLine) {
291 StartedNewLine =
true;
293 EmittedTokensOnThisLine =
false;
294 EmittedDirectiveOnThisLine =
false;
299 if (CurLine == LineNo) {
301 }
else if (MinimizeWhitespace && DisableLineMarkers) {
303 }
else if (!StartedNewLine && LineNo - CurLine == 1) {
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);
315 WriteLineInfo(LineNo,
nullptr, 0);
317 StartedNewLine =
true;
318 }
else if (EmittedTokensOnThisLine) {
322 StartedNewLine =
true;
325 if (StartedNewLine) {
326 EmittedTokensOnThisLine =
false;
327 EmittedDirectiveOnThisLine =
false;
331 return StartedNewLine;
334void PrintPPOutputPPCallbacks::startNewLineIfNeeded() {
335 if (EmittedTokensOnThisLine || EmittedDirectiveOnThisLine) {
337 EmittedTokensOnThisLine =
false;
338 EmittedDirectiveOnThisLine =
false;
346 FileChangeReason Reason,
362 MoveToLine(IncludeLoc,
false);
382 if (DisableLineMarkers) {
383 if (!MinimizeWhitespace)
384 startNewLineIfNeeded();
389 WriteLineInfo(CurLine);
398 IsFirstFileEntered =
true;
404 WriteLineInfo(CurLine,
" 1", 2);
407 WriteLineInfo(CurLine,
" 2", 2);
411 WriteLineInfo(CurLine);
416void PrintPPOutputPPCallbacks::EmbedDirective(
419 if (!DumpEmbedDirectives)
432 MoveToLine(HashLoc,
true);
433 *OS <<
"#embed " << (IsAngled ?
'<' :
'"') <<
FileName
434 << (IsAngled ?
'>' :
'"');
438 for (
const Token &
T : Toks) {
439 if (
T.hasLeadingSpace())
444 bool SkipAnnotToks =
true;
453 SkipAnnotToks =
false;
480 *OS <<
" /* clang -E -dE */";
481 setEmittedDirectiveOnThisLine();
484void PrintPPOutputPPCallbacks::InclusionDirective(
487 StringRef SearchPath, StringRef RelativePath,
const Module *SuggestedModule,
492 MoveToLine(HashLoc,
true);
493 const std::string TokenText = PP.
getSpelling(IncludeTok);
494 assert(!TokenText.empty());
495 *OS <<
"#" << TokenText <<
" "
496 << (IsAngled ?
'<' :
'"') <<
FileName << (IsAngled ?
'>' :
'"')
498 << (DumpIncludeDirectives ?
"-dI" :
"-fkeep-system-includes")
500 setEmittedDirectiveOnThisLine();
504 if (ModuleImported) {
506 case tok::pp_include:
508 case tok::pp_include_next:
509 MoveToLine(HashLoc,
true);
510 *OS <<
"#pragma clang module import "
512 <<
" /* clang -E: implicit import for "
514 << (IsAngled ?
'<' :
'"') <<
FileName << (IsAngled ?
'>' :
'"')
516 setEmittedDirectiveOnThisLine();
519 case tok::pp___include_macros:
528 llvm_unreachable(
"unknown include directive kind");
535void PrintPPOutputPPCallbacks::BeginModule(
const Module *M) {
536 startNewLineIfNeeded();
538 setEmittedDirectiveOnThisLine();
542void PrintPPOutputPPCallbacks::EndModule(
const Module *M) {
543 startNewLineIfNeeded();
545 setEmittedDirectiveOnThisLine();
551 MoveToLine(
Loc,
true);
553 OS->write(
"#ident ", strlen(
"#ident "));
554 OS->write(S.begin(), S.size());
555 setEmittedTokensOnThisLine();
559void PrintPPOutputPPCallbacks::MacroDefined(
const Token &MacroNameTok,
564 if ((!DumpDefines && !DirectivesOnly) ||
570 if (DirectivesOnly && !MI->
isUsed()) {
572 if (
SM.isWrittenInBuiltinFile(DefLoc) ||
573 SM.isWrittenInCommandLineFile(DefLoc))
576 MoveToLine(DefLoc,
true);
578 setEmittedDirectiveOnThisLine();
581void PrintPPOutputPPCallbacks::MacroUndefined(
const Token &MacroNameTok,
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));
608 PragmaMessageKind Kind,
610 MoveToLine(
Loc,
true);
628 if (Kind == PMK_Message)
630 setEmittedDirectiveOnThisLine();
634 StringRef DebugType) {
635 MoveToLine(
Loc,
true);
637 *OS <<
"#pragma clang __debug ";
640 setEmittedDirectiveOnThisLine();
643void PrintPPOutputPPCallbacks::
645 MoveToLine(
Loc,
true);
646 *OS <<
"#pragma " <<
Namespace <<
" diagnostic push";
647 setEmittedDirectiveOnThisLine();
650void PrintPPOutputPPCallbacks::
652 MoveToLine(
Loc,
true);
653 *OS <<
"#pragma " <<
Namespace <<
" diagnostic pop";
654 setEmittedDirectiveOnThisLine();
661 MoveToLine(
Loc,
true);
662 *OS <<
"#pragma " <<
Namespace <<
" diagnostic ";
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();
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;
706 setEmittedDirectiveOnThisLine();
711 MoveToLine(
Loc,
true);
712 *OS <<
"#pragma warning(push";
714 *OS <<
", " <<
Level;
716 setEmittedDirectiveOnThisLine();
720 MoveToLine(
Loc,
true);
721 *OS <<
"#pragma warning(pop)";
722 setEmittedDirectiveOnThisLine();
727 MoveToLine(
Loc,
true);
728 *OS <<
"#pragma character_execution_set(push";
732 setEmittedDirectiveOnThisLine();
736 MoveToLine(
Loc,
true);
737 *OS <<
"#pragma character_execution_set(pop)";
738 setEmittedDirectiveOnThisLine();
741void PrintPPOutputPPCallbacks::
743 MoveToLine(
Loc,
true);
744 *OS <<
"#pragma clang assume_nonnull begin";
745 setEmittedDirectiveOnThisLine();
748void PrintPPOutputPPCallbacks::
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)))
767 if ((!RequireSameLine || EmittedDirectiveOnThisLine) &&
768 MoveToLine(Tok, EmittedDirectiveOnThisLine)) {
769 if (MinimizeWhitespace) {
771 if (Tok.
is(tok::hash))
776 unsigned ColNo =
SM.getExpansionColumnNumber(Tok.
getLocation());
791 if (ColNo <= 1 && Tok.
is(tok::hash))
795 for (; ColNo > 1; --ColNo)
806 ((EmittedTokensOnThisLine || EmittedDirectiveOnThisLine) &&
807 AvoidConcat(PrevPrevTok, PrevTok, Tok)))
811 PrevPrevTok = PrevTok;
815void PrintPPOutputPPCallbacks::HandleNewlinesInToken(
const char *TokStr,
817 unsigned NumNewlines = 0;
818 for (; Len; --Len, ++TokStr) {
819 if (*TokStr !=
'\n' &&
827 (TokStr[1] ==
'\n' || TokStr[1] ==
'\r') &&
828 TokStr[0] != TokStr[1]) {
834 if (NumNewlines == 0)
return;
836 CurLine += NumNewlines;
843 PrintPPOutputPPCallbacks *Callbacks;
846 bool ShouldExpandTokens;
848 UnknownPragmaHandler(
const char *prefix, PrintPPOutputPPCallbacks *callbacks,
849 bool RequireTokenExpansion)
850 : Prefix(prefix), Callbacks(callbacks),
851 ShouldExpandTokens(RequireTokenExpansion) {}
853 Token &PragmaTok)
override {
856 Callbacks->MoveToLine(PragmaTok.
getLocation(),
true);
857 Callbacks->OS->write(Prefix, strlen(Prefix));
858 Callbacks->setEmittedTokensOnThisLine();
860 if (ShouldExpandTokens) {
863 auto Toks = std::make_unique<Token[]>(1);
865 PP.EnterTokenStream(std::move(Toks), 1,
873 while (PragmaTok.
isNot(tok::eod)) {
874 Callbacks->HandleWhitespaceBeforeTok(PragmaTok, IsFirst,
878 Callbacks->OS->write(&TokSpell[0], TokSpell.size());
879 Callbacks->setEmittedTokensOnThisLine();
881 if (ShouldExpandTokens)
886 Callbacks->setEmittedDirectiveOnThisLine();
893 PrintPPOutputPPCallbacks *Callbacks) {
894 bool DropComments = PP.
getLangOpts().TraditionalCPP &&
897 bool IsStartOfLine =
false;
909 Callbacks->HandleWhitespaceBeforeTok(Tok,
false,
912 if (DropComments && Tok.
is(tok::comment)) {
918 }
else if (Tok.
is(tok::annot_repl_input_end)) {
920 }
else if (Tok.
is(tok::eod)) {
927 IsStartOfLine =
true;
929 }
else if (Tok.
is(tok::annot_module_include)) {
933 IsStartOfLine =
true;
935 }
else if (Tok.
is(tok::annot_module_begin)) {
942 Callbacks->BeginModule(
945 IsStartOfLine =
true;
947 }
else if (Tok.
is(tok::annot_module_end)) {
948 Callbacks->EndModule(
951 IsStartOfLine =
true;
953 }
else if (Tok.
is(tok::annot_header_unit)) {
960 Callbacks->OS->write(Name.data(), Name.size());
961 Callbacks->HandleNewlinesInToken(Name.data(), Name.size());
962 }
else if (Tok.
is(tok::annot_embed)) {
967 assert(Callbacks->expandEmbedContents() &&
968 "did not expect an embed annotation");
974 bool PrintComma =
false;
975 for (
auto Iter =
Data->BinaryData.begin(), End =
Data->BinaryData.end();
978 *Callbacks->OS <<
", ";
979 *Callbacks->OS <<
static_cast<unsigned>(*Iter);
988 *Callbacks->OS << II->getName();
992 }
else if (Tok.
getLength() < std::size(Buffer)) {
993 const char *TokPtr = Buffer;
995 Callbacks->OS->write(TokPtr, Len);
1002 if (Tok.
getKind() == tok::comment || Tok.
getKind() == tok::unknown)
1003 Callbacks->HandleNewlinesInToken(TokPtr, Len);
1004 if (Tok.
is(tok::comment) && Len >= 2 && TokPtr[0] ==
'/' &&
1008 Callbacks->setEmittedDirectiveOnThisLine();
1012 Callbacks->OS->write(S.data(), S.size());
1016 if (Tok.
getKind() == tok::comment || Tok.
getKind() == tok::unknown)
1017 Callbacks->HandleNewlinesInToken(S.data(), S.size());
1018 if (Tok.
is(tok::comment) && S.size() >= 2 && S[0] ==
'/' && S[1] ==
'/') {
1021 Callbacks->setEmittedDirectiveOnThisLine();
1024 Callbacks->setEmittedTokensOnThisLine();
1025 IsStartOfLine =
false;
1027 if (Tok.
is(tok::eof) || Tok.
is(tok::annot_repl_input_end))
1032 for (
unsigned I = 0, Skip = Callbacks->GetNumToksToSkip(); I < Skip; ++I)
1034 Callbacks->ResetSkipToks();
1040 return LHS->first->getName().compare(RHS->first->getName());
1056 auto *MD = I->second.getLatest();
1057 if (MD && MD->isDefined())
1060 llvm::array_pod_sort(MacrosByID.begin(), MacrosByID.end(),
MacroIDCompare);
1062 for (
unsigned i = 0, e = MacrosByID.size(); i != e; ++i) {
1078 assert(Opts.
ShowMacros &&
"Not yet implemented!");
1087 PrintPPOutputPPCallbacks *Callbacks =
new PrintPPOutputPPCallbacks(
1096 std::unique_ptr<UnknownPragmaHandler> MicrosoftExtHandler(
1097 new UnknownPragmaHandler(
1098 "#pragma", Callbacks,
1101 std::unique_ptr<UnknownPragmaHandler> GCCHandler(
new UnknownPragmaHandler(
1102 "#pragma GCC", Callbacks,
1105 std::unique_ptr<UnknownPragmaHandler> ClangHandler(
new UnknownPragmaHandler(
1106 "#pragma clang", Callbacks,
1118 std::unique_ptr<UnknownPragmaHandler> OpenMPHandler(
1119 new UnknownPragmaHandler(
"#pragma omp", Callbacks,
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.
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.
MacroInfo * getMacroInfo() const
Get the MacroInfo that should be used for this definition.
Encapsulates changes to the "macros namespace" (the location where the macro name became active,...
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.
virtual void PragmaExecCharsetPop(SourceLocation Loc)
Callback invoked when a #pragma execution_character_set(pop) directive is read.
virtual void PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace)
Callback invoked when a #pragma gcc diagnostic push directive is read.
virtual void PragmaWarning(SourceLocation Loc, PragmaWarningSpecifier WarningSpec, ArrayRef< int > Ids)
virtual void PragmaDebug(SourceLocation Loc, StringRef DebugType)
Callback invoked when a #pragma clang __debug directive is read.
virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason, SrcMgr::CharacteristicKind FileType, FileID PrevFID=FileID())
Callback invoked whenever a source file is entered or exited.
virtual void MacroUndefined(const Token &MacroNameTok, const MacroDefinition &MD, const MacroDirective *Undef)
Hook called whenever a macro #undef is seen.
virtual void MacroDefined(const Token &MacroNameTok, const MacroDirective *MD)
Hook called whenever a macro definition is seen.
virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace, diag::Severity mapping, StringRef Str)
Callback invoked when a #pragma gcc diagnostic directive is read.
virtual void PragmaAssumeNonNullEnd(SourceLocation Loc)
Callback invoked when a #pragma clang assume_nonnull end directive is read.
virtual void PragmaAssumeNonNullBegin(SourceLocation Loc)
Callback invoked when a #pragma clang assume_nonnull begin directive is read.
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...
virtual void Ident(SourceLocation Loc, StringRef str)
Callback invoked when a #ident or #sccs directive is read.
virtual void PragmaMessage(SourceLocation Loc, StringRef Namespace, PragmaMessageKind Kind, StringRef Str)
Callback invoked when a #pragma message directive is read.
virtual void PragmaExecCharsetPush(SourceLocation Loc, StringRef Str)
Callback invoked when a #pragma execution_character_set(push) directive is read.
virtual void PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace)
Callback invoked when a #pragma gcc diagnostic pop directive is read.
virtual void PragmaWarningPop(SourceLocation Loc)
Callback invoked when a #pragma warning(pop) directive is read.
virtual void PragmaWarningPush(SourceLocation Loc, int Level)
Callback invoked when a #pragma warning(push) directive is read.
PragmaHandler - Instances of this interface defined to handle the various pragmas that the language f...
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 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.
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.
IdentifierInfo * getIdentifierInfo() const
bool isLiteral() const
Return true if this is a "literal", like a numeric constant, string, etc.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
unsigned getLength() const
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)) {....
void * getAnnotationValue() const
tok::TokenKind getKind() const
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.
void startToken()
Reset all flags to cleared.
bool needsCleaning() const
Return true if this token has trigraphs or escaped newlines in it.
const char * getLiteralData() const
getLiteralData - For a literal token (numeric constant, string, etc), this returns a pointer to the s...
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),...
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 ...
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.