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 UseLineDirectives;
97 bool IsFirstFileEntered;
98 bool MinimizeWhitespace;
100 bool KeepSystemIncludes;
102 std::unique_ptr<llvm::raw_null_ostream> NullOS;
108 PrintPPOutputPPCallbacks(
Preprocessor &pp, raw_ostream *os,
bool lineMarkers,
109 bool defines,
bool DumpIncludeDirectives,
110 bool UseLineDirectives,
bool MinimizeWhitespace,
111 bool DirectivesOnly,
bool KeepSystemIncludes)
112 : PP(pp),
SM(PP.getSourceManager()), ConcatInfo(PP), OS(os),
113 DisableLineMarkers(lineMarkers), DumpDefines(defines),
114 DumpIncludeDirectives(DumpIncludeDirectives),
115 UseLineDirectives(UseLineDirectives),
116 MinimizeWhitespace(MinimizeWhitespace), DirectivesOnly(DirectivesOnly),
117 KeepSystemIncludes(KeepSystemIncludes), OrigOS(os) {
119 CurFilename +=
"<uninit>";
120 EmittedTokensOnThisLine =
false;
121 EmittedDirectiveOnThisLine =
false;
124 IsFirstFileEntered =
false;
125 if (KeepSystemIncludes)
126 NullOS = std::make_unique<llvm::raw_null_ostream>();
132 bool isMinimizeWhitespace()
const {
return MinimizeWhitespace; }
134 void setEmittedTokensOnThisLine() { EmittedTokensOnThisLine =
true; }
135 bool hasEmittedTokensOnThisLine()
const {
return EmittedTokensOnThisLine; }
137 void setEmittedDirectiveOnThisLine() { EmittedDirectiveOnThisLine =
true; }
138 bool hasEmittedDirectiveOnThisLine()
const {
139 return EmittedDirectiveOnThisLine;
147 void startNewLineIfNeeded();
156 StringRef RelativePath,
const Module *SuggestedModule,
161 PragmaMessageKind Kind, StringRef Str)
override;
183 void HandleWhitespaceBeforeTok(
const Token &Tok,
bool RequireSpace,
184 bool RequireSameLine);
198 bool MoveToLine(
const Token &Tok,
bool RequireStartOfLine) {
203 return MoveToLine(TargetLine, RequireStartOfLine) || IsFirstInFile;
211 return MoveToLine(TargetLine, RequireStartOfLine);
213 bool MoveToLine(
unsigned LineNo,
bool RequireStartOfLine);
215 bool AvoidConcat(
const Token &PrevPrevTok,
const Token &PrevTok,
217 return ConcatInfo.
AvoidConcat(PrevPrevTok, PrevTok, Tok);
219 void WriteLineInfo(
unsigned LineNo,
const char *Extra=
nullptr,
220 unsigned ExtraLen=0);
221 bool LineMarkersAreDisabled()
const {
return DisableLineMarkers; }
222 void HandleNewlinesInToken(
const char *TokStr,
unsigned Len);
233 void BeginModule(
const Module *M);
234 void EndModule(
const Module *M);
238void PrintPPOutputPPCallbacks::WriteLineInfo(
unsigned LineNo,
241 startNewLineIfNeeded();
244 if (UseLineDirectives) {
245 *OS <<
"#line" <<
' ' << LineNo <<
' ' <<
'"';
246 OS->write_escaped(CurFilename);
249 *OS <<
'#' <<
' ' << LineNo <<
' ' <<
'"';
250 OS->write_escaped(CurFilename);
254 OS->write(Extra, ExtraLen);
259 OS->write(
" 3 4", 4);
268bool PrintPPOutputPPCallbacks::MoveToLine(
unsigned LineNo,
269 bool RequireStartOfLine) {
273 bool StartedNewLine =
false;
274 if ((RequireStartOfLine && EmittedTokensOnThisLine) ||
275 EmittedDirectiveOnThisLine) {
277 StartedNewLine =
true;
279 EmittedTokensOnThisLine =
false;
280 EmittedDirectiveOnThisLine =
false;
285 if (CurLine == LineNo) {
287 }
else if (MinimizeWhitespace && DisableLineMarkers) {
289 }
else if (!StartedNewLine && LineNo - CurLine == 1) {
294 StartedNewLine =
true;
295 }
else if (!DisableLineMarkers) {
296 if (LineNo - CurLine <= 8) {
297 const char *NewLines =
"\n\n\n\n\n\n\n\n";
298 OS->write(NewLines, LineNo - CurLine);
301 WriteLineInfo(LineNo,
nullptr, 0);
303 StartedNewLine =
true;
304 }
else if (EmittedTokensOnThisLine) {
308 StartedNewLine =
true;
311 if (StartedNewLine) {
312 EmittedTokensOnThisLine =
false;
313 EmittedDirectiveOnThisLine =
false;
317 return StartedNewLine;
320void PrintPPOutputPPCallbacks::startNewLineIfNeeded() {
321 if (EmittedTokensOnThisLine || EmittedDirectiveOnThisLine) {
323 EmittedTokensOnThisLine =
false;
324 EmittedDirectiveOnThisLine =
false;
332 FileChangeReason Reason,
348 MoveToLine(IncludeLoc,
false);
368 if (DisableLineMarkers) {
369 if (!MinimizeWhitespace)
370 startNewLineIfNeeded();
375 WriteLineInfo(CurLine);
384 IsFirstFileEntered =
true;
390 WriteLineInfo(CurLine,
" 1", 2);
393 WriteLineInfo(CurLine,
" 2", 2);
397 WriteLineInfo(CurLine);
402void PrintPPOutputPPCallbacks::InclusionDirective(
405 StringRef SearchPath, StringRef RelativePath,
const Module *SuggestedModule,
410 MoveToLine(HashLoc,
true);
411 const std::string TokenText = PP.
getSpelling(IncludeTok);
412 assert(!TokenText.empty());
413 *OS <<
"#" << TokenText <<
" "
414 << (IsAngled ?
'<' :
'"') <<
FileName << (IsAngled ?
'>' :
'"')
416 << (DumpIncludeDirectives ?
"-dI" :
"-fkeep-system-includes")
418 setEmittedDirectiveOnThisLine();
422 if (ModuleImported) {
424 case tok::pp_include:
426 case tok::pp_include_next:
427 MoveToLine(HashLoc,
true);
428 *OS <<
"#pragma clang module import "
430 <<
" /* clang -E: implicit import for "
432 << (IsAngled ?
'<' :
'"') <<
FileName << (IsAngled ?
'>' :
'"')
434 setEmittedDirectiveOnThisLine();
437 case tok::pp___include_macros:
446 llvm_unreachable(
"unknown include directive kind");
453void PrintPPOutputPPCallbacks::BeginModule(
const Module *M) {
454 startNewLineIfNeeded();
456 setEmittedDirectiveOnThisLine();
460void PrintPPOutputPPCallbacks::EndModule(
const Module *M) {
461 startNewLineIfNeeded();
463 setEmittedDirectiveOnThisLine();
468void PrintPPOutputPPCallbacks::Ident(
SourceLocation Loc, StringRef S) {
469 MoveToLine(Loc,
true);
471 OS->write(
"#ident ", strlen(
"#ident "));
472 OS->write(S.begin(), S.size());
473 setEmittedTokensOnThisLine();
477void PrintPPOutputPPCallbacks::MacroDefined(
const Token &MacroNameTok,
482 if ((!DumpDefines && !DirectivesOnly) ||
488 if (DirectivesOnly && !MI->
isUsed()) {
490 if (
SM.isWrittenInBuiltinFile(DefLoc) ||
491 SM.isWrittenInCommandLineFile(DefLoc))
494 MoveToLine(DefLoc,
true);
496 setEmittedDirectiveOnThisLine();
499void PrintPPOutputPPCallbacks::MacroUndefined(
const Token &MacroNameTok,
504 if (!DumpDefines && !DirectivesOnly)
509 setEmittedDirectiveOnThisLine();
513 for (
unsigned char Char : Str) {
514 if (
isPrintable(Char) && Char !=
'\\' && Char !=
'"')
518 << (char)(
'0' + ((Char >> 6) & 7))
519 << (char)(
'0' + ((Char >> 3) & 7))
520 << (char)(
'0' + ((Char >> 0) & 7));
526 PragmaMessageKind Kind,
528 MoveToLine(Loc,
true);
546 if (Kind == PMK_Message)
548 setEmittedDirectiveOnThisLine();
552 StringRef DebugType) {
553 MoveToLine(Loc,
true);
555 *OS <<
"#pragma clang __debug ";
558 setEmittedDirectiveOnThisLine();
561void PrintPPOutputPPCallbacks::
563 MoveToLine(Loc,
true);
564 *OS <<
"#pragma " <<
Namespace <<
" diagnostic push";
565 setEmittedDirectiveOnThisLine();
568void PrintPPOutputPPCallbacks::
570 MoveToLine(Loc,
true);
571 *OS <<
"#pragma " <<
Namespace <<
" diagnostic pop";
572 setEmittedDirectiveOnThisLine();
575void PrintPPOutputPPCallbacks::PragmaDiagnostic(
SourceLocation Loc,
579 MoveToLine(Loc,
true);
580 *OS <<
"#pragma " <<
Namespace <<
" diagnostic ";
582 case diag::Severity::Remark:
585 case diag::Severity::Warning:
588 case diag::Severity::Error:
591 case diag::Severity::Ignored:
594 case diag::Severity::Fatal:
598 *OS <<
" \"" << Str <<
'"';
599 setEmittedDirectiveOnThisLine();
603 PragmaWarningSpecifier WarningSpec,
605 MoveToLine(Loc,
true);
607 *OS <<
"#pragma warning(";
608 switch(WarningSpec) {
609 case PWS_Default: *OS <<
"default";
break;
610 case PWS_Disable: *OS <<
"disable";
break;
611 case PWS_Error: *OS <<
"error";
break;
612 case PWS_Once: *OS <<
"once";
break;
613 case PWS_Suppress: *OS <<
"suppress";
break;
614 case PWS_Level1: *OS <<
'1';
break;
615 case PWS_Level2: *OS <<
'2';
break;
616 case PWS_Level3: *OS <<
'3';
break;
617 case PWS_Level4: *OS <<
'4';
break;
624 setEmittedDirectiveOnThisLine();
627void PrintPPOutputPPCallbacks::PragmaWarningPush(
SourceLocation Loc,
629 MoveToLine(Loc,
true);
630 *OS <<
"#pragma warning(push";
632 *OS <<
", " <<
Level;
634 setEmittedDirectiveOnThisLine();
637void PrintPPOutputPPCallbacks::PragmaWarningPop(
SourceLocation Loc) {
638 MoveToLine(Loc,
true);
639 *OS <<
"#pragma warning(pop)";
640 setEmittedDirectiveOnThisLine();
643void PrintPPOutputPPCallbacks::PragmaExecCharsetPush(
SourceLocation Loc,
645 MoveToLine(Loc,
true);
646 *OS <<
"#pragma character_execution_set(push";
650 setEmittedDirectiveOnThisLine();
653void PrintPPOutputPPCallbacks::PragmaExecCharsetPop(
SourceLocation Loc) {
654 MoveToLine(Loc,
true);
655 *OS <<
"#pragma character_execution_set(pop)";
656 setEmittedDirectiveOnThisLine();
659void PrintPPOutputPPCallbacks::
661 MoveToLine(Loc,
true);
662 *OS <<
"#pragma clang assume_nonnull begin";
663 setEmittedDirectiveOnThisLine();
666void PrintPPOutputPPCallbacks::
668 MoveToLine(Loc,
true);
669 *OS <<
"#pragma clang assume_nonnull end";
670 setEmittedDirectiveOnThisLine();
673void PrintPPOutputPPCallbacks::HandleWhitespaceBeforeTok(
const Token &Tok,
675 bool RequireSameLine) {
678 if (Tok.
is(tok::eof) ||
680 !Tok.
is(tok::annot_module_begin) && !Tok.
is(tok::annot_module_end) &&
681 !Tok.
is(tok::annot_repl_input_end)))
685 if ((!RequireSameLine || EmittedDirectiveOnThisLine) &&
686 MoveToLine(Tok, EmittedDirectiveOnThisLine)) {
687 if (MinimizeWhitespace) {
689 if (Tok.
is(tok::hash))
694 unsigned ColNo =
SM.getExpansionColumnNumber(Tok.
getLocation());
709 if (ColNo <= 1 && Tok.
is(tok::hash))
713 for (; ColNo > 1; --ColNo)
724 ((EmittedTokensOnThisLine || EmittedDirectiveOnThisLine) &&
725 AvoidConcat(PrevPrevTok, PrevTok, Tok)))
729 PrevPrevTok = PrevTok;
733void PrintPPOutputPPCallbacks::HandleNewlinesInToken(
const char *TokStr,
735 unsigned NumNewlines = 0;
736 for (; Len; --Len, ++TokStr) {
737 if (*TokStr !=
'\n' &&
745 (TokStr[1] ==
'\n' || TokStr[1] ==
'\r') &&
746 TokStr[0] != TokStr[1]) {
752 if (NumNewlines == 0)
return;
754 CurLine += NumNewlines;
761 PrintPPOutputPPCallbacks *Callbacks;
764 bool ShouldExpandTokens;
766 UnknownPragmaHandler(
const char *prefix, PrintPPOutputPPCallbacks *callbacks,
767 bool RequireTokenExpansion)
768 : Prefix(prefix), Callbacks(callbacks),
769 ShouldExpandTokens(RequireTokenExpansion) {}
771 Token &PragmaTok)
override {
774 Callbacks->MoveToLine(PragmaTok.
getLocation(),
true);
775 Callbacks->OS->write(Prefix, strlen(Prefix));
776 Callbacks->setEmittedTokensOnThisLine();
778 if (ShouldExpandTokens) {
781 auto Toks = std::make_unique<Token[]>(1);
783 PP.EnterTokenStream(std::move(Toks), 1,
791 while (PragmaTok.
isNot(tok::eod)) {
792 Callbacks->HandleWhitespaceBeforeTok(PragmaTok, IsFirst,
796 Callbacks->OS->write(&TokSpell[0], TokSpell.size());
797 Callbacks->setEmittedTokensOnThisLine();
799 if (ShouldExpandTokens)
804 Callbacks->setEmittedDirectiveOnThisLine();
811 PrintPPOutputPPCallbacks *Callbacks) {
812 bool DropComments = PP.
getLangOpts().TraditionalCPP &&
815 bool IsStartOfLine =
false;
827 Callbacks->HandleWhitespaceBeforeTok(Tok,
false,
830 if (DropComments && Tok.
is(tok::comment)) {
836 }
else if (Tok.
is(tok::annot_repl_input_end)) {
839 }
else if (Tok.
is(tok::eod)) {
846 IsStartOfLine =
true;
848 }
else if (Tok.
is(tok::annot_module_include)) {
852 IsStartOfLine =
true;
854 }
else if (Tok.
is(tok::annot_module_begin)) {
861 Callbacks->BeginModule(
864 IsStartOfLine =
true;
866 }
else if (Tok.
is(tok::annot_module_end)) {
867 Callbacks->EndModule(
870 IsStartOfLine =
true;
872 }
else if (Tok.
is(tok::annot_header_unit)) {
879 Callbacks->OS->write(Name.data(), Name.size());
880 Callbacks->HandleNewlinesInToken(Name.data(), Name.size());
887 *Callbacks->OS << II->getName();
891 }
else if (Tok.
getLength() < std::size(Buffer)) {
892 const char *TokPtr = Buffer;
894 Callbacks->OS->write(TokPtr, Len);
901 if (Tok.
getKind() == tok::comment || Tok.
getKind() == tok::unknown)
902 Callbacks->HandleNewlinesInToken(TokPtr, Len);
903 if (Tok.
is(tok::comment) && Len >= 2 && TokPtr[0] ==
'/' &&
907 Callbacks->setEmittedDirectiveOnThisLine();
911 Callbacks->OS->write(S.data(), S.size());
915 if (Tok.
getKind() == tok::comment || Tok.
getKind() == tok::unknown)
916 Callbacks->HandleNewlinesInToken(S.data(), S.size());
917 if (Tok.
is(tok::comment) && S.size() >= 2 && S[0] ==
'/' && S[1] ==
'/') {
920 Callbacks->setEmittedDirectiveOnThisLine();
923 Callbacks->setEmittedTokensOnThisLine();
924 IsStartOfLine =
false;
926 if (Tok.
is(tok::eof))
break;
934 return LHS->first->getName().compare(RHS->first->getName());
947 while (Tok.
isNot(tok::eof));
952 auto *MD = I->second.getLatest();
953 if (MD && MD->isDefined())
956 llvm::array_pod_sort(MacrosByID.begin(), MacrosByID.end(),
MacroIDCompare);
958 for (
unsigned i = 0, e = MacrosByID.size(); i != e; ++i) {
974 assert(Opts.
ShowMacros &&
"Not yet implemented!");
983 PrintPPOutputPPCallbacks *Callbacks =
new PrintPPOutputPPCallbacks(
991 std::unique_ptr<UnknownPragmaHandler> MicrosoftExtHandler(
992 new UnknownPragmaHandler(
993 "#pragma", Callbacks,
996 std::unique_ptr<UnknownPragmaHandler> GCCHandler(
new UnknownPragmaHandler(
997 "#pragma GCC", Callbacks,
1000 std::unique_ptr<UnknownPragmaHandler> ClangHandler(
new UnknownPragmaHandler(
1001 "#pragma clang", Callbacks,
1013 std::unique_ptr<UnknownPragmaHandler> OpenMPHandler(
1014 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 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 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 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
Describes how and where the pragma was introduced.