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 {
87 bool EmittedTokensOnThisLine;
88 bool EmittedDirectiveOnThisLine;
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>();
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();
166 StringRef RelativePath,
const Module *SuggestedModule,
171 PragmaMessageKind Kind, StringRef Str)
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;
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);
243 void BeginModule(
const Module *M);
244 void EndModule(
const Module *M);
246 unsigned GetNumToksToSkip()
const {
return NumToksToSkip; }
247 void ResetSkipToks() { NumToksToSkip = 0; }
251void PrintPPOutputPPCallbacks::WriteLineInfo(
unsigned LineNo,
254 startNewLineIfNeeded();
257 if (UseLineDirectives) {
258 *OS <<
"#line" <<
' ' << LineNo <<
' ' <<
'"';
259 OS->write_escaped(CurFilename);
262 *OS <<
'#' <<
' ' << LineNo <<
' ' <<
'"';
263 OS->write_escaped(CurFilename);
267 OS->write(
Extra, ExtraLen);
272 OS->write(
" 3 4", 4);
281bool PrintPPOutputPPCallbacks::MoveToLine(
unsigned LineNo,
282 bool RequireStartOfLine) {
286 bool StartedNewLine =
false;
287 if ((RequireStartOfLine && EmittedTokensOnThisLine) ||
288 EmittedDirectiveOnThisLine) {
290 StartedNewLine =
true;
292 EmittedTokensOnThisLine =
false;
293 EmittedDirectiveOnThisLine =
false;
298 if (CurLine == LineNo) {
300 }
else if (MinimizeWhitespace && DisableLineMarkers) {
302 }
else if (!StartedNewLine && LineNo - CurLine == 1) {
307 StartedNewLine =
true;
308 }
else if (!DisableLineMarkers) {
309 if (LineNo - CurLine <= 8) {
310 const char *NewLines =
"\n\n\n\n\n\n\n\n";
311 OS->write(NewLines, LineNo - CurLine);
314 WriteLineInfo(LineNo,
nullptr, 0);
316 StartedNewLine =
true;
317 }
else if (EmittedTokensOnThisLine) {
321 StartedNewLine =
true;
324 if (StartedNewLine) {
325 EmittedTokensOnThisLine =
false;
326 EmittedDirectiveOnThisLine =
false;
330 return StartedNewLine;
333void PrintPPOutputPPCallbacks::startNewLineIfNeeded() {
334 if (EmittedTokensOnThisLine || EmittedDirectiveOnThisLine) {
336 EmittedTokensOnThisLine =
false;
337 EmittedDirectiveOnThisLine =
false;
345 FileChangeReason Reason,
361 MoveToLine(IncludeLoc,
false);
381 if (DisableLineMarkers) {
382 if (!MinimizeWhitespace)
383 startNewLineIfNeeded();
388 WriteLineInfo(CurLine);
397 IsFirstFileEntered =
true;
403 WriteLineInfo(CurLine,
" 1", 2);
406 WriteLineInfo(CurLine,
" 2", 2);
410 WriteLineInfo(CurLine);
415void PrintPPOutputPPCallbacks::EmbedDirective(
418 if (!DumpEmbedDirectives)
431 MoveToLine(HashLoc,
true);
432 *OS <<
"#embed " << (IsAngled ?
'<' :
'"') <<
FileName
433 << (IsAngled ?
'>' :
'"');
437 for (
const Token &
T : Toks) {
438 if (
T.hasLeadingSpace())
443 bool SkipAnnotToks =
true;
452 SkipAnnotToks =
false;
479 *OS <<
" /* clang -E -dE */";
480 setEmittedDirectiveOnThisLine();
483void PrintPPOutputPPCallbacks::InclusionDirective(
486 StringRef SearchPath, StringRef RelativePath,
const Module *SuggestedModule,
491 MoveToLine(HashLoc,
true);
492 const std::string TokenText = PP.
getSpelling(IncludeTok);
493 assert(!TokenText.empty());
494 *OS <<
"#" << TokenText <<
" "
495 << (IsAngled ?
'<' :
'"') <<
FileName << (IsAngled ?
'>' :
'"')
497 << (DumpIncludeDirectives ?
"-dI" :
"-fkeep-system-includes")
499 setEmittedDirectiveOnThisLine();
503 if (ModuleImported) {
505 case tok::pp_include:
507 case tok::pp_include_next:
508 MoveToLine(HashLoc,
true);
509 *OS <<
"#pragma clang module import "
511 <<
" /* clang -E: implicit import for "
513 << (IsAngled ?
'<' :
'"') <<
FileName << (IsAngled ?
'>' :
'"')
515 setEmittedDirectiveOnThisLine();
518 case tok::pp___include_macros:
527 llvm_unreachable(
"unknown include directive kind");
534void PrintPPOutputPPCallbacks::BeginModule(
const Module *M) {
535 startNewLineIfNeeded();
537 setEmittedDirectiveOnThisLine();
541void PrintPPOutputPPCallbacks::EndModule(
const Module *M) {
542 startNewLineIfNeeded();
544 setEmittedDirectiveOnThisLine();
550 MoveToLine(
Loc,
true);
552 OS->write(
"#ident ", strlen(
"#ident "));
553 OS->write(S.begin(), S.size());
554 setEmittedTokensOnThisLine();
558void PrintPPOutputPPCallbacks::MacroDefined(
const Token &MacroNameTok,
563 if ((!DumpDefines && !DirectivesOnly) ||
569 if (DirectivesOnly && !MI->
isUsed()) {
571 if (
SM.isInPredefinedFile(DefLoc))
574 MoveToLine(DefLoc,
true);
576 setEmittedDirectiveOnThisLine();
579void PrintPPOutputPPCallbacks::MacroUndefined(
const Token &MacroNameTok,
584 if (!DumpDefines && !DirectivesOnly)
589 setEmittedDirectiveOnThisLine();
593 for (
unsigned char Char : Str) {
594 if (
isPrintable(Char) && Char !=
'\\' && Char !=
'"')
598 << (char)(
'0' + ((Char >> 6) & 7))
599 << (char)(
'0' + ((Char >> 3) & 7))
600 << (char)(
'0' + ((Char >> 0) & 7));
606 PragmaMessageKind Kind,
608 MoveToLine(
Loc,
true);
626 if (Kind == PMK_Message)
628 setEmittedDirectiveOnThisLine();
632 StringRef DebugType) {
633 MoveToLine(
Loc,
true);
635 *OS <<
"#pragma clang __debug ";
638 setEmittedDirectiveOnThisLine();
641void PrintPPOutputPPCallbacks::
643 MoveToLine(
Loc,
true);
644 *OS <<
"#pragma " <<
Namespace <<
" diagnostic push";
645 setEmittedDirectiveOnThisLine();
648void PrintPPOutputPPCallbacks::
650 MoveToLine(
Loc,
true);
651 *OS <<
"#pragma " <<
Namespace <<
" diagnostic pop";
652 setEmittedDirectiveOnThisLine();
659 MoveToLine(
Loc,
true);
660 *OS <<
"#pragma " <<
Namespace <<
" diagnostic ";
662 case diag::Severity::Remark:
665 case diag::Severity::Warning:
668 case diag::Severity::Error:
671 case diag::Severity::Ignored:
674 case diag::Severity::Fatal:
678 *OS <<
" \"" << Str <<
'"';
679 setEmittedDirectiveOnThisLine();
683 PragmaWarningSpecifier WarningSpec,
685 MoveToLine(
Loc,
true);
687 *OS <<
"#pragma warning(";
688 switch(WarningSpec) {
689 case PWS_Default: *OS <<
"default";
break;
690 case PWS_Disable: *OS <<
"disable";
break;
691 case PWS_Error: *OS <<
"error";
break;
692 case PWS_Once: *OS <<
"once";
break;
693 case PWS_Suppress: *OS <<
"suppress";
break;
694 case PWS_Level1: *OS <<
'1';
break;
695 case PWS_Level2: *OS <<
'2';
break;
696 case PWS_Level3: *OS <<
'3';
break;
697 case PWS_Level4: *OS <<
'4';
break;
704 setEmittedDirectiveOnThisLine();
709 MoveToLine(
Loc,
true);
710 *OS <<
"#pragma warning(push";
712 *OS <<
", " <<
Level;
714 setEmittedDirectiveOnThisLine();
718 MoveToLine(
Loc,
true);
719 *OS <<
"#pragma warning(pop)";
720 setEmittedDirectiveOnThisLine();
725 MoveToLine(
Loc,
true);
726 *OS <<
"#pragma character_execution_set(push";
730 setEmittedDirectiveOnThisLine();
734 MoveToLine(
Loc,
true);
735 *OS <<
"#pragma character_execution_set(pop)";
736 setEmittedDirectiveOnThisLine();
739void PrintPPOutputPPCallbacks::
741 MoveToLine(
Loc,
true);
742 *OS <<
"#pragma clang assume_nonnull begin";
743 setEmittedDirectiveOnThisLine();
746void PrintPPOutputPPCallbacks::
748 MoveToLine(
Loc,
true);
749 *OS <<
"#pragma clang assume_nonnull end";
750 setEmittedDirectiveOnThisLine();
753void PrintPPOutputPPCallbacks::HandleWhitespaceBeforeTok(
const Token &Tok,
755 bool RequireSameLine) {
758 if (Tok.
is(tok::eof) ||
760 !Tok.
is(tok::annot_module_begin) && !Tok.
is(tok::annot_module_end) &&
761 !Tok.
is(tok::annot_repl_input_end) && !Tok.
is(tok::annot_embed)))
765 if ((!RequireSameLine || EmittedDirectiveOnThisLine) &&
766 MoveToLine(Tok, EmittedDirectiveOnThisLine)) {
767 if (MinimizeWhitespace) {
769 if (Tok.
is(tok::hash))
774 unsigned ColNo =
SM.getExpansionColumnNumber(Tok.
getLocation());
789 if (ColNo <= 1 && Tok.
is(tok::hash))
793 for (; ColNo > 1; --ColNo)
804 ((EmittedTokensOnThisLine || EmittedDirectiveOnThisLine) &&
805 AvoidConcat(PrevPrevTok, PrevTok, Tok)))
809 PrevPrevTok = PrevTok;
813void PrintPPOutputPPCallbacks::HandleNewlinesInToken(
const char *TokStr,
815 unsigned NumNewlines = 0;
816 for (; Len; --Len, ++TokStr) {
817 if (*TokStr !=
'\n' &&
825 (TokStr[1] ==
'\n' || TokStr[1] ==
'\r') &&
826 TokStr[0] != TokStr[1]) {
832 if (NumNewlines == 0)
return;
834 CurLine += NumNewlines;
841 PrintPPOutputPPCallbacks *Callbacks;
844 bool ShouldExpandTokens;
846 UnknownPragmaHandler(
const char *prefix, PrintPPOutputPPCallbacks *callbacks,
847 bool RequireTokenExpansion)
848 : Prefix(prefix), Callbacks(callbacks),
849 ShouldExpandTokens(RequireTokenExpansion) {}
851 Token &PragmaTok)
override {
854 Callbacks->MoveToLine(PragmaTok.
getLocation(),
true);
855 Callbacks->OS->write(Prefix, strlen(Prefix));
856 Callbacks->setEmittedTokensOnThisLine();
858 if (ShouldExpandTokens) {
861 auto Toks = std::make_unique<Token[]>(1);
863 PP.EnterTokenStream(std::move(Toks), 1,
871 while (PragmaTok.
isNot(tok::eod)) {
872 Callbacks->HandleWhitespaceBeforeTok(PragmaTok, IsFirst,
876 Callbacks->OS->write(&TokSpell[0], TokSpell.size());
877 Callbacks->setEmittedTokensOnThisLine();
879 if (ShouldExpandTokens)
884 Callbacks->setEmittedDirectiveOnThisLine();
891 PrintPPOutputPPCallbacks *Callbacks) {
892 bool DropComments = PP.
getLangOpts().TraditionalCPP &&
895 bool IsStartOfLine =
false;
907 Callbacks->HandleWhitespaceBeforeTok(Tok,
false,
910 if (DropComments && Tok.
is(tok::comment)) {
916 }
else if (Tok.
is(tok::annot_repl_input_end)) {
918 }
else if (Tok.
is(tok::eod)) {
925 IsStartOfLine =
true;
927 }
else if (Tok.
is(tok::annot_module_include)) {
931 IsStartOfLine =
true;
933 }
else if (Tok.
is(tok::annot_module_begin)) {
940 Callbacks->BeginModule(
943 IsStartOfLine =
true;
945 }
else if (Tok.
is(tok::annot_module_end)) {
946 Callbacks->EndModule(
949 IsStartOfLine =
true;
951 }
else if (Tok.
is(tok::annot_header_unit)) {
959 *Callbacks->OS <<
'"';
960 Callbacks->OS->write_escaped(Name);
961 *Callbacks->OS <<
'"';
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 (
unsigned char Byte :
Data->BinaryData.bytes()) {
977 *Callbacks->OS <<
", ";
978 *Callbacks->OS <<
static_cast<int>(Byte);
987 *Callbacks->OS << II->getName();
991 }
else if (Tok.
getLength() < std::size(Buffer)) {
992 const char *TokPtr = Buffer;
994 Callbacks->OS->write(TokPtr, Len);
1001 if (Tok.
getKind() == tok::comment || Tok.
getKind() == tok::unknown)
1002 Callbacks->HandleNewlinesInToken(TokPtr, Len);
1003 if (Tok.
is(tok::comment) && Len >= 2 && TokPtr[0] ==
'/' &&
1007 Callbacks->setEmittedDirectiveOnThisLine();
1011 Callbacks->OS->write(S.data(), S.size());
1015 if (Tok.
getKind() == tok::comment || Tok.
getKind() == tok::unknown)
1016 Callbacks->HandleNewlinesInToken(S.data(), S.size());
1017 if (Tok.
is(tok::comment) && S.size() >= 2 && S[0] ==
'/' && S[1] ==
'/') {
1020 Callbacks->setEmittedDirectiveOnThisLine();
1023 Callbacks->setEmittedTokensOnThisLine();
1024 IsStartOfLine =
false;
1026 if (Tok.
is(tok::eof) || Tok.
is(tok::annot_repl_input_end))
1031 for (
unsigned I = 0,
Skip = Callbacks->GetNumToksToSkip(); I <
Skip; ++I)
1033 Callbacks->ResetSkipToks();
1039 return LHS->first->getName().compare(RHS->first->getName());
1055 auto *MD = I->second.getLatest();
1056 if (MD && MD->isDefined())
1059 llvm::array_pod_sort(MacrosByID.begin(), MacrosByID.end(),
MacroIDCompare);
1061 for (
unsigned i = 0, e = MacrosByID.size(); i != e; ++i) {
1077 assert(Opts.
ShowMacros &&
"Not yet implemented!");
1086 PrintPPOutputPPCallbacks *Callbacks =
new PrintPPOutputPPCallbacks(
1095 std::unique_ptr<UnknownPragmaHandler> MicrosoftExtHandler(
1096 new UnknownPragmaHandler(
1097 "#pragma", Callbacks,
1100 std::unique_ptr<UnknownPragmaHandler> GCCHandler(
new UnknownPragmaHandler(
1101 "#pragma GCC", Callbacks,
1104 std::unique_ptr<UnknownPragmaHandler> ClangHandler(
new UnknownPragmaHandler(
1105 "#pragma clang", Callbacks,
1117 std::unique_ptr<UnknownPragmaHandler> OpenMPHandler(
1118 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.