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 *Imported,
160 PragmaMessageKind Kind, StringRef Str)
override;
182 void HandleWhitespaceBeforeTok(
const Token &Tok,
bool RequireSpace,
183 bool RequireSameLine);
197 bool MoveToLine(
const Token &Tok,
bool RequireStartOfLine) {
202 return MoveToLine(TargetLine, RequireStartOfLine) || IsFirstInFile;
210 return MoveToLine(TargetLine, RequireStartOfLine);
212 bool MoveToLine(
unsigned LineNo,
bool RequireStartOfLine);
214 bool AvoidConcat(
const Token &PrevPrevTok,
const Token &PrevTok,
216 return ConcatInfo.
AvoidConcat(PrevPrevTok, PrevTok, Tok);
218 void WriteLineInfo(
unsigned LineNo,
const char *Extra=
nullptr,
219 unsigned ExtraLen=0);
220 bool LineMarkersAreDisabled()
const {
return DisableLineMarkers; }
221 void HandleNewlinesInToken(
const char *TokStr,
unsigned Len);
232 void BeginModule(
const Module *M);
233 void EndModule(
const Module *M);
237void PrintPPOutputPPCallbacks::WriteLineInfo(
unsigned LineNo,
240 startNewLineIfNeeded();
243 if (UseLineDirectives) {
244 *OS <<
"#line" <<
' ' << LineNo <<
' ' <<
'"';
245 OS->write_escaped(CurFilename);
248 *OS <<
'#' <<
' ' << LineNo <<
' ' <<
'"';
249 OS->write_escaped(CurFilename);
253 OS->write(Extra, ExtraLen);
258 OS->write(
" 3 4", 4);
267bool PrintPPOutputPPCallbacks::MoveToLine(
unsigned LineNo,
268 bool RequireStartOfLine) {
272 bool StartedNewLine =
false;
273 if ((RequireStartOfLine && EmittedTokensOnThisLine) ||
274 EmittedDirectiveOnThisLine) {
276 StartedNewLine =
true;
278 EmittedTokensOnThisLine =
false;
279 EmittedDirectiveOnThisLine =
false;
284 if (CurLine == LineNo) {
286 }
else if (MinimizeWhitespace && DisableLineMarkers) {
288 }
else if (!StartedNewLine && LineNo - CurLine == 1) {
293 StartedNewLine =
true;
294 }
else if (!DisableLineMarkers) {
295 if (LineNo - CurLine <= 8) {
296 const char *NewLines =
"\n\n\n\n\n\n\n\n";
297 OS->write(NewLines, LineNo - CurLine);
300 WriteLineInfo(LineNo,
nullptr, 0);
302 StartedNewLine =
true;
303 }
else if (EmittedTokensOnThisLine) {
307 StartedNewLine =
true;
310 if (StartedNewLine) {
311 EmittedTokensOnThisLine =
false;
312 EmittedDirectiveOnThisLine =
false;
316 return StartedNewLine;
319void PrintPPOutputPPCallbacks::startNewLineIfNeeded() {
320 if (EmittedTokensOnThisLine || EmittedDirectiveOnThisLine) {
322 EmittedTokensOnThisLine =
false;
323 EmittedDirectiveOnThisLine =
false;
331 FileChangeReason Reason,
347 MoveToLine(IncludeLoc,
false);
361 OS =
isSystem(FileType) ? OrigOS : NullOS.get();
365 FileType = NewFileType;
367 if (DisableLineMarkers) {
368 if (!MinimizeWhitespace)
369 startNewLineIfNeeded();
374 WriteLineInfo(CurLine);
383 IsFirstFileEntered =
true;
389 WriteLineInfo(CurLine,
" 1", 2);
392 WriteLineInfo(CurLine,
" 2", 2);
396 WriteLineInfo(CurLine);
401void PrintPPOutputPPCallbacks::InclusionDirective(
404 StringRef SearchPath, StringRef RelativePath,
const Module *Imported,
408 if (DumpIncludeDirectives || (KeepSystemIncludes &&
isSystem(FileType))) {
409 MoveToLine(HashLoc,
true);
410 const std::string TokenText = PP.
getSpelling(IncludeTok);
411 assert(!TokenText.empty());
412 *OS <<
"#" << TokenText <<
" "
413 << (IsAngled ?
'<' :
'"') <<
FileName << (IsAngled ?
'>' :
'"')
415 << (DumpIncludeDirectives ?
"-dI" :
"-fkeep-system-includes")
417 setEmittedDirectiveOnThisLine();
423 case tok::pp_include:
425 case tok::pp_include_next:
426 MoveToLine(HashLoc,
true);
427 *OS <<
"#pragma clang module import "
429 <<
" /* clang -E: implicit import for "
431 << (IsAngled ?
'<' :
'"') <<
FileName << (IsAngled ?
'>' :
'"')
433 setEmittedDirectiveOnThisLine();
436 case tok::pp___include_macros:
445 llvm_unreachable(
"unknown include directive kind");
452void PrintPPOutputPPCallbacks::BeginModule(
const Module *M) {
453 startNewLineIfNeeded();
455 setEmittedDirectiveOnThisLine();
459void PrintPPOutputPPCallbacks::EndModule(
const Module *M) {
460 startNewLineIfNeeded();
462 setEmittedDirectiveOnThisLine();
467void PrintPPOutputPPCallbacks::Ident(
SourceLocation Loc, StringRef S) {
468 MoveToLine(Loc,
true);
470 OS->write(
"#ident ", strlen(
"#ident "));
471 OS->write(S.begin(), S.size());
472 setEmittedTokensOnThisLine();
476void PrintPPOutputPPCallbacks::MacroDefined(
const Token &MacroNameTok,
481 if ((!DumpDefines && !DirectivesOnly) ||
487 if (DirectivesOnly && !MI->
isUsed()) {
489 if (
SM.isWrittenInBuiltinFile(DefLoc) ||
490 SM.isWrittenInCommandLineFile(DefLoc))
493 MoveToLine(DefLoc,
true);
495 setEmittedDirectiveOnThisLine();
498void PrintPPOutputPPCallbacks::MacroUndefined(
const Token &MacroNameTok,
503 if (!DumpDefines && !DirectivesOnly)
508 setEmittedDirectiveOnThisLine();
512 for (
unsigned char Char : Str) {
513 if (
isPrintable(Char) && Char !=
'\\' && Char !=
'"')
517 << (char)(
'0' + ((Char >> 6) & 7))
518 << (char)(
'0' + ((Char >> 3) & 7))
519 << (char)(
'0' + ((Char >> 0) & 7));
525 PragmaMessageKind Kind,
527 MoveToLine(Loc,
true);
545 if (Kind == PMK_Message)
547 setEmittedDirectiveOnThisLine();
551 StringRef DebugType) {
552 MoveToLine(Loc,
true);
554 *OS <<
"#pragma clang __debug ";
557 setEmittedDirectiveOnThisLine();
560void PrintPPOutputPPCallbacks::
562 MoveToLine(Loc,
true);
563 *OS <<
"#pragma " <<
Namespace <<
" diagnostic push";
564 setEmittedDirectiveOnThisLine();
567void PrintPPOutputPPCallbacks::
569 MoveToLine(Loc,
true);
570 *OS <<
"#pragma " <<
Namespace <<
" diagnostic pop";
571 setEmittedDirectiveOnThisLine();
574void PrintPPOutputPPCallbacks::PragmaDiagnostic(
SourceLocation Loc,
578 MoveToLine(Loc,
true);
579 *OS <<
"#pragma " <<
Namespace <<
" diagnostic ";
581 case diag::Severity::Remark:
584 case diag::Severity::Warning:
587 case diag::Severity::Error:
590 case diag::Severity::Ignored:
593 case diag::Severity::Fatal:
597 *OS <<
" \"" << Str <<
'"';
598 setEmittedDirectiveOnThisLine();
602 PragmaWarningSpecifier WarningSpec,
604 MoveToLine(Loc,
true);
606 *OS <<
"#pragma warning(";
607 switch(WarningSpec) {
608 case PWS_Default: *OS <<
"default";
break;
609 case PWS_Disable: *OS <<
"disable";
break;
610 case PWS_Error: *OS <<
"error";
break;
611 case PWS_Once: *OS <<
"once";
break;
612 case PWS_Suppress: *OS <<
"suppress";
break;
613 case PWS_Level1: *OS <<
'1';
break;
614 case PWS_Level2: *OS <<
'2';
break;
615 case PWS_Level3: *OS <<
'3';
break;
616 case PWS_Level4: *OS <<
'4';
break;
623 setEmittedDirectiveOnThisLine();
626void PrintPPOutputPPCallbacks::PragmaWarningPush(
SourceLocation Loc,
628 MoveToLine(Loc,
true);
629 *OS <<
"#pragma warning(push";
631 *OS <<
", " <<
Level;
633 setEmittedDirectiveOnThisLine();
636void PrintPPOutputPPCallbacks::PragmaWarningPop(
SourceLocation Loc) {
637 MoveToLine(Loc,
true);
638 *OS <<
"#pragma warning(pop)";
639 setEmittedDirectiveOnThisLine();
642void PrintPPOutputPPCallbacks::PragmaExecCharsetPush(
SourceLocation Loc,
644 MoveToLine(Loc,
true);
645 *OS <<
"#pragma character_execution_set(push";
649 setEmittedDirectiveOnThisLine();
652void PrintPPOutputPPCallbacks::PragmaExecCharsetPop(
SourceLocation Loc) {
653 MoveToLine(Loc,
true);
654 *OS <<
"#pragma character_execution_set(pop)";
655 setEmittedDirectiveOnThisLine();
658void PrintPPOutputPPCallbacks::
660 MoveToLine(Loc,
true);
661 *OS <<
"#pragma clang assume_nonnull begin";
662 setEmittedDirectiveOnThisLine();
665void PrintPPOutputPPCallbacks::
667 MoveToLine(Loc,
true);
668 *OS <<
"#pragma clang assume_nonnull end";
669 setEmittedDirectiveOnThisLine();
672void PrintPPOutputPPCallbacks::HandleWhitespaceBeforeTok(
const Token &Tok,
674 bool RequireSameLine) {
677 if (Tok.
is(tok::eof) ||
679 !Tok.
is(tok::annot_module_begin) && !Tok.
is(tok::annot_module_end) &&
680 !Tok.
is(tok::annot_repl_input_end)))
684 if ((!RequireSameLine || EmittedDirectiveOnThisLine) &&
685 MoveToLine(Tok, EmittedDirectiveOnThisLine)) {
686 if (MinimizeWhitespace) {
688 if (Tok.
is(tok::hash))
693 unsigned ColNo =
SM.getExpansionColumnNumber(Tok.
getLocation());
708 if (ColNo <= 1 && Tok.
is(tok::hash))
712 for (; ColNo > 1; --ColNo)
723 ((EmittedTokensOnThisLine || EmittedDirectiveOnThisLine) &&
724 AvoidConcat(PrevPrevTok, PrevTok, Tok)))
728 PrevPrevTok = PrevTok;
732void PrintPPOutputPPCallbacks::HandleNewlinesInToken(
const char *TokStr,
734 unsigned NumNewlines = 0;
735 for (; Len; --Len, ++TokStr) {
736 if (*TokStr !=
'\n' &&
744 (TokStr[1] ==
'\n' || TokStr[1] ==
'\r') &&
745 TokStr[0] != TokStr[1]) {
751 if (NumNewlines == 0)
return;
753 CurLine += NumNewlines;
760 PrintPPOutputPPCallbacks *Callbacks;
763 bool ShouldExpandTokens;
765 UnknownPragmaHandler(
const char *prefix, PrintPPOutputPPCallbacks *callbacks,
766 bool RequireTokenExpansion)
767 : Prefix(prefix), Callbacks(callbacks),
768 ShouldExpandTokens(RequireTokenExpansion) {}
770 Token &PragmaTok)
override {
773 Callbacks->MoveToLine(PragmaTok.
getLocation(),
true);
774 Callbacks->OS->write(Prefix, strlen(Prefix));
775 Callbacks->setEmittedTokensOnThisLine();
777 if (ShouldExpandTokens) {
780 auto Toks = std::make_unique<Token[]>(1);
782 PP.EnterTokenStream(std::move(Toks), 1,
790 while (PragmaTok.
isNot(tok::eod)) {
791 Callbacks->HandleWhitespaceBeforeTok(PragmaTok, IsFirst,
795 Callbacks->OS->write(&TokSpell[0], TokSpell.size());
796 Callbacks->setEmittedTokensOnThisLine();
798 if (ShouldExpandTokens)
803 Callbacks->setEmittedDirectiveOnThisLine();
810 PrintPPOutputPPCallbacks *Callbacks) {
811 bool DropComments = PP.
getLangOpts().TraditionalCPP &&
814 bool IsStartOfLine =
false;
826 Callbacks->HandleWhitespaceBeforeTok(Tok,
false,
829 if (DropComments && Tok.
is(tok::comment)) {
835 }
else if (Tok.
is(tok::annot_repl_input_end)) {
838 }
else if (Tok.
is(tok::eod)) {
845 IsStartOfLine =
true;
847 }
else if (Tok.
is(tok::annot_module_include)) {
851 IsStartOfLine =
true;
853 }
else if (Tok.
is(tok::annot_module_begin)) {
860 Callbacks->BeginModule(
863 IsStartOfLine =
true;
865 }
else if (Tok.
is(tok::annot_module_end)) {
866 Callbacks->EndModule(
869 IsStartOfLine =
true;
871 }
else if (Tok.
is(tok::annot_header_unit)) {
878 Callbacks->OS->write(Name.data(), Name.size());
879 Callbacks->HandleNewlinesInToken(Name.data(), Name.size());
886 *Callbacks->OS << II->getName();
890 }
else if (Tok.
getLength() < std::size(Buffer)) {
891 const char *TokPtr = Buffer;
893 Callbacks->OS->write(TokPtr, Len);
900 if (Tok.
getKind() == tok::comment || Tok.
getKind() == tok::unknown)
901 Callbacks->HandleNewlinesInToken(TokPtr, Len);
902 if (Tok.
is(tok::comment) && Len >= 2 && TokPtr[0] ==
'/' &&
906 Callbacks->setEmittedDirectiveOnThisLine();
910 Callbacks->OS->write(S.data(), S.size());
914 if (Tok.
getKind() == tok::comment || Tok.
getKind() == tok::unknown)
915 Callbacks->HandleNewlinesInToken(S.data(), S.size());
916 if (Tok.
is(tok::comment) && S.size() >= 2 && S[0] ==
'/' && S[1] ==
'/') {
919 Callbacks->setEmittedDirectiveOnThisLine();
922 Callbacks->setEmittedTokensOnThisLine();
923 IsStartOfLine =
false;
925 if (Tok.
is(tok::eof))
break;
933 return LHS->first->getName().compare(RHS->first->getName());
946 while (Tok.
isNot(tok::eof));
951 auto *MD = I->second.getLatest();
952 if (MD && MD->isDefined())
955 llvm::array_pod_sort(MacrosByID.begin(), MacrosByID.end(),
MacroIDCompare);
957 for (
unsigned i = 0, e = MacrosByID.size(); i != e; ++i) {
973 assert(Opts.
ShowMacros &&
"Not yet implemented!");
982 PrintPPOutputPPCallbacks *Callbacks =
new PrintPPOutputPPCallbacks(
990 std::unique_ptr<UnknownPragmaHandler> MicrosoftExtHandler(
991 new UnknownPragmaHandler(
992 "#pragma", Callbacks,
995 std::unique_ptr<UnknownPragmaHandler> GCCHandler(
new UnknownPragmaHandler(
996 "#pragma GCC", Callbacks,
999 std::unique_ptr<UnknownPragmaHandler> ClangHandler(
new UnknownPragmaHandler(
1000 "#pragma clang", Callbacks,
1012 std::unique_ptr<UnknownPragmaHandler> OpenMPHandler(
1013 new UnknownPragmaHandler(
"#pragma omp", Callbacks,
Defines the Diagnostic-related interfaces.
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),...
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.
Describes how and where the pragma was introduced.