25 #include "llvm/ADT/STLExtras.h"
26 #include "llvm/ADT/SmallString.h"
27 #include "llvm/ADT/StringRef.h"
28 #include "llvm/Support/ErrorHandling.h"
29 #include "llvm/Support/raw_ostream.h"
31 using namespace clang;
37 *OS <<
"#define " << II.
getName();
43 for (; AI+1 !=
E; ++AI) {
44 *OS << (*AI)->getName();
49 if ((*AI)->getName() ==
"__VA_ARGS__")
52 *OS << (*AI)->getName();
67 for (
const auto &
T : MI.
tokens()) {
68 if (
T.hasLeadingSpace())
80 class PrintPPOutputPPCallbacks :
public PPCallbacks {
89 bool EmittedTokensOnThisLine;
90 bool EmittedDirectiveOnThisLine;
94 bool DisableLineMarkers;
96 bool DumpIncludeDirectives;
97 bool DumpEmbedDirectives;
98 bool UseLineDirectives;
99 bool IsFirstFileEntered;
100 bool MinimizeWhitespace;
102 bool KeepSystemIncludes;
104 std::unique_ptr<llvm::raw_null_ostream> NullOS;
105 unsigned NumToksToSkip;
111 PrintPPOutputPPCallbacks(
Preprocessor &pp, raw_ostream *os,
bool lineMarkers,
112 bool defines,
bool DumpIncludeDirectives,
113 bool DumpEmbedDirectives,
bool UseLineDirectives,
114 bool MinimizeWhitespace,
bool DirectivesOnly,
115 bool KeepSystemIncludes)
116 : PP(pp),
SM(PP.getSourceManager()), ConcatInfo(PP), OS(os),
117 DisableLineMarkers(lineMarkers), DumpDefines(defines),
118 DumpIncludeDirectives(DumpIncludeDirectives),
119 DumpEmbedDirectives(DumpEmbedDirectives),
120 UseLineDirectives(UseLineDirectives),
121 MinimizeWhitespace(MinimizeWhitespace), DirectivesOnly(DirectivesOnly),
122 KeepSystemIncludes(KeepSystemIncludes), OrigOS(os), NumToksToSkip(0) {
124 CurFilename +=
"<uninit>";
125 EmittedTokensOnThisLine =
false;
126 EmittedDirectiveOnThisLine =
false;
129 IsFirstFileEntered =
false;
130 if (KeepSystemIncludes)
131 NullOS = std::make_unique<llvm::raw_null_ostream>();
139 bool expandEmbedContents()
const {
return !DumpEmbedDirectives; }
141 bool isMinimizeWhitespace()
const {
return MinimizeWhitespace; }
143 void setEmittedTokensOnThisLine() { EmittedTokensOnThisLine =
true; }
144 bool hasEmittedTokensOnThisLine()
const {
return EmittedTokensOnThisLine; }
146 void setEmittedDirectiveOnThisLine() { EmittedDirectiveOnThisLine =
true; }
147 bool hasEmittedDirectiveOnThisLine()
const {
148 return EmittedDirectiveOnThisLine;
156 void startNewLineIfNeeded();
161 void EmbedDirective(
SourceLocation HashLoc, StringRef FileName,
bool IsAngled,
165 StringRef FileName,
bool IsAngled,
168 StringRef RelativePath,
const Module *SuggestedModule,
173 PragmaMessageKind
Kind, StringRef Str)
override;
195 void HandleWhitespaceBeforeTok(
const Token &Tok,
bool RequireSpace,
196 bool RequireSameLine);
210 bool MoveToLine(
const Token &Tok,
bool RequireStartOfLine) {
215 return MoveToLine(TargetLine, RequireStartOfLine) || IsFirstInFile;
223 return MoveToLine(TargetLine, RequireStartOfLine);
225 bool MoveToLine(
unsigned LineNo,
bool RequireStartOfLine);
227 bool AvoidConcat(
const Token &PrevPrevTok,
const Token &PrevTok,
229 return ConcatInfo.
AvoidConcat(PrevPrevTok, PrevTok, Tok);
231 void WriteFooterInfo(StringRef Footer);
232 void WriteFooterContent(StringRef CodeFooter);
233 void WriteLineInfo(
unsigned LineNo,
const char *Extra=
nullptr,
234 unsigned ExtraLen=0);
235 bool LineMarkersAreDisabled()
const {
return DisableLineMarkers; }
236 void HandleNewlinesInToken(
const char *TokStr,
unsigned Len);
239 void MacroDefined(
const Token &MacroNameTok,
243 void MacroUndefined(
const Token &MacroNameTok,
247 void BeginModule(
const Module *M);
248 void EndModule(
const Module *M);
250 unsigned GetNumToksToSkip()
const {
return NumToksToSkip; }
251 void ResetSkipToks() { NumToksToSkip = 0; }
255 void PrintPPOutputPPCallbacks::WriteFooterInfo(StringRef Footer) {
256 *OS <<
'#' <<
' ' << 1 <<
' ' <<
'"';
257 *OS <<
"<built-in>" <<
'"' <<
' ' <<
"1";
259 *OS << Twine(
"# 1 ") +
"\"" + Footer +
"\"" + Twine(
" 1");
263 void PrintPPOutputPPCallbacks::WriteFooterContent(StringRef CodeFooter) {
268 void PrintPPOutputPPCallbacks::WriteLineInfo(
unsigned LineNo,
271 startNewLineIfNeeded();
274 if (UseLineDirectives) {
275 *OS <<
"#line" <<
' ' << LineNo <<
' ' <<
'"';
276 OS->write_escaped(CurFilename);
279 *OS <<
'#' <<
' ' << LineNo <<
' ' <<
'"';
280 OS->write_escaped(CurFilename);
284 OS->write(Extra, ExtraLen);
289 OS->write(
" 3 4", 4);
298 bool PrintPPOutputPPCallbacks::MoveToLine(
unsigned LineNo,
299 bool RequireStartOfLine) {
303 bool StartedNewLine =
false;
304 if ((RequireStartOfLine && EmittedTokensOnThisLine) ||
305 EmittedDirectiveOnThisLine) {
307 StartedNewLine =
true;
309 EmittedTokensOnThisLine =
false;
310 EmittedDirectiveOnThisLine =
false;
315 if (CurLine == LineNo) {
317 }
else if (MinimizeWhitespace && DisableLineMarkers) {
319 }
else if (!StartedNewLine && LineNo - CurLine == 1) {
324 StartedNewLine =
true;
325 }
else if (!DisableLineMarkers) {
326 if (LineNo - CurLine <= 8) {
327 const char *NewLines =
"\n\n\n\n\n\n\n\n";
328 OS->write(NewLines, LineNo - CurLine);
331 WriteLineInfo(LineNo,
nullptr, 0);
333 StartedNewLine =
true;
334 }
else if (EmittedTokensOnThisLine) {
338 StartedNewLine =
true;
341 if (StartedNewLine) {
342 EmittedTokensOnThisLine =
false;
343 EmittedDirectiveOnThisLine =
false;
347 return StartedNewLine;
350 void PrintPPOutputPPCallbacks::startNewLineIfNeeded() {
351 if (EmittedTokensOnThisLine || EmittedDirectiveOnThisLine) {
353 EmittedTokensOnThisLine =
false;
354 EmittedDirectiveOnThisLine =
false;
362 FileChangeReason Reason,
378 MoveToLine(IncludeLoc,
false);
398 if (DisableLineMarkers) {
399 if (!MinimizeWhitespace)
400 startNewLineIfNeeded();
405 WriteLineInfo(CurLine);
414 IsFirstFileEntered =
true;
420 WriteLineInfo(CurLine,
" 1", 2);
423 WriteLineInfo(CurLine,
" 2", 2);
427 WriteLineInfo(CurLine);
432 void PrintPPOutputPPCallbacks::EmbedDirective(
435 if (!DumpEmbedDirectives)
448 MoveToLine(HashLoc,
true);
449 *OS <<
"#embed " << (IsAngled ?
'<' :
'"') << FileName
450 << (IsAngled ?
'>' :
'"');
454 for (
const Token &
T : Toks) {
455 if (
T.hasLeadingSpace())
460 bool SkipAnnotToks =
true;
467 if (File && !
File->getSize()) {
469 SkipAnnotToks =
false;
496 *OS <<
" /* clang -E -dE */";
497 setEmittedDirectiveOnThisLine();
500 void PrintPPOutputPPCallbacks::InclusionDirective(
503 StringRef SearchPath, StringRef RelativePath,
const Module *SuggestedModule,
508 MoveToLine(HashLoc,
true);
509 const std::string TokenText = PP.
getSpelling(IncludeTok);
510 assert(!TokenText.empty());
511 *OS <<
"#" << TokenText <<
" "
512 << (IsAngled ?
'<' :
'"') << FileName << (IsAngled ?
'>' :
'"')
514 << (DumpIncludeDirectives ?
"-dI" :
"-fkeep-system-includes")
516 setEmittedDirectiveOnThisLine();
520 if (ModuleImported) {
525 MoveToLine(HashLoc,
true);
526 *OS <<
"#pragma clang module import "
528 <<
" /* clang -E: implicit import for "
530 << (IsAngled ?
'<' :
'"') << FileName << (IsAngled ?
'>' :
'"')
532 setEmittedDirectiveOnThisLine();
544 llvm_unreachable(
"unknown include directive kind");
551 void PrintPPOutputPPCallbacks::BeginModule(
const Module *M) {
552 startNewLineIfNeeded();
554 setEmittedDirectiveOnThisLine();
558 void PrintPPOutputPPCallbacks::EndModule(
const Module *M) {
559 startNewLineIfNeeded();
561 setEmittedDirectiveOnThisLine();
567 MoveToLine(
Loc,
true);
569 OS->write(
"#ident ", strlen(
"#ident "));
570 OS->write(S.begin(), S.size());
571 setEmittedTokensOnThisLine();
575 void PrintPPOutputPPCallbacks::MacroDefined(
const Token &MacroNameTok,
580 if ((!DumpDefines && !DirectivesOnly) ||
586 if (DirectivesOnly && !MI->
isUsed()) {
588 if (
SM.isWrittenInBuiltinFile(DefLoc) ||
589 SM.isWrittenInCommandLineFile(DefLoc))
592 MoveToLine(DefLoc,
true);
594 setEmittedDirectiveOnThisLine();
597 void PrintPPOutputPPCallbacks::MacroUndefined(
const Token &MacroNameTok,
602 if (!DumpDefines && !DirectivesOnly)
607 setEmittedDirectiveOnThisLine();
611 for (
unsigned char Char : Str) {
612 if (
isPrintable(Char) && Char !=
'\\' && Char !=
'"')
616 << (char)(
'0' + ((Char >> 6) & 7))
617 << (char)(
'0' + ((Char >> 3) & 7))
618 << (char)(
'0' + ((Char >> 0) & 7));
624 PragmaMessageKind
Kind,
626 MoveToLine(
Loc,
true);
644 if (
Kind == PMK_Message)
646 setEmittedDirectiveOnThisLine();
650 StringRef DebugType) {
651 MoveToLine(
Loc,
true);
653 *OS <<
"#pragma clang __debug ";
656 setEmittedDirectiveOnThisLine();
659 void PrintPPOutputPPCallbacks::
661 MoveToLine(
Loc,
true);
662 *OS <<
"#pragma " <<
Namespace <<
" diagnostic push";
663 setEmittedDirectiveOnThisLine();
666 void PrintPPOutputPPCallbacks::
668 MoveToLine(
Loc,
true);
669 *OS <<
"#pragma " <<
Namespace <<
" diagnostic pop";
670 setEmittedDirectiveOnThisLine();
677 MoveToLine(
Loc,
true);
678 *OS <<
"#pragma " <<
Namespace <<
" diagnostic ";
696 *OS <<
" \"" << Str <<
'"';
697 setEmittedDirectiveOnThisLine();
701 PragmaWarningSpecifier WarningSpec,
703 MoveToLine(
Loc,
true);
705 *OS <<
"#pragma warning(";
706 switch(WarningSpec) {
707 case PWS_Default: *OS <<
"default";
break;
708 case PWS_Disable: *OS <<
"disable";
break;
709 case PWS_Error: *OS <<
"error";
break;
710 case PWS_Once: *OS <<
"once";
break;
711 case PWS_Suppress: *OS <<
"suppress";
break;
712 case PWS_Level1: *OS <<
'1';
break;
713 case PWS_Level2: *OS <<
'2';
break;
714 case PWS_Level3: *OS <<
'3';
break;
715 case PWS_Level4: *OS <<
'4';
break;
722 setEmittedDirectiveOnThisLine();
727 MoveToLine(
Loc,
true);
728 *OS <<
"#pragma warning(push";
730 *OS <<
", " <<
Level;
732 setEmittedDirectiveOnThisLine();
736 MoveToLine(
Loc,
true);
737 *OS <<
"#pragma warning(pop)";
738 setEmittedDirectiveOnThisLine();
743 MoveToLine(
Loc,
true);
744 *OS <<
"#pragma character_execution_set(push";
748 setEmittedDirectiveOnThisLine();
752 MoveToLine(
Loc,
true);
753 *OS <<
"#pragma character_execution_set(pop)";
754 setEmittedDirectiveOnThisLine();
757 void PrintPPOutputPPCallbacks::
759 MoveToLine(
Loc,
true);
760 *OS <<
"#pragma clang assume_nonnull begin";
761 setEmittedDirectiveOnThisLine();
764 void PrintPPOutputPPCallbacks::
766 MoveToLine(
Loc,
true);
767 *OS <<
"#pragma clang assume_nonnull end";
768 setEmittedDirectiveOnThisLine();
771 void PrintPPOutputPPCallbacks::HandleWhitespaceBeforeTok(
const Token &Tok,
773 bool RequireSameLine) {
778 !Tok.
is(tok::annot_module_begin) && !Tok.
is(tok::annot_module_end) &&
779 !Tok.
is(tok::annot_repl_input_end) && !Tok.
is(tok::annot_embed)))
783 if ((!RequireSameLine || EmittedDirectiveOnThisLine) &&
784 MoveToLine(Tok, EmittedDirectiveOnThisLine)) {
785 if (MinimizeWhitespace) {
787 if (Tok.
is(tok::hash))
792 unsigned ColNo =
SM.getExpansionColumnNumber(Tok.
getLocation());
807 if (ColNo <= 1 && Tok.
is(tok::hash))
811 for (; ColNo > 1; --ColNo)
822 ((EmittedTokensOnThisLine || EmittedDirectiveOnThisLine) &&
823 AvoidConcat(PrevPrevTok, PrevTok, Tok)))
827 PrevPrevTok = PrevTok;
831 void PrintPPOutputPPCallbacks::HandleNewlinesInToken(
const char *TokStr,
833 unsigned NumNewlines = 0;
834 for (; Len; --Len, ++TokStr) {
835 if (*TokStr !=
'\n' &&
843 (TokStr[1] ==
'\n' || TokStr[1] ==
'\r') &&
844 TokStr[0] != TokStr[1]) {
850 if (NumNewlines == 0)
return;
852 CurLine += NumNewlines;
859 PrintPPOutputPPCallbacks *Callbacks;
862 bool ShouldExpandTokens;
864 UnknownPragmaHandler(
const char *prefix, PrintPPOutputPPCallbacks *callbacks,
865 bool RequireTokenExpansion)
866 : Prefix(prefix), Callbacks(callbacks),
867 ShouldExpandTokens(RequireTokenExpansion) {}
869 Token &PragmaTok)
override {
872 Callbacks->MoveToLine(PragmaTok.
getLocation(),
true);
873 Callbacks->OS->write(Prefix, strlen(Prefix));
874 Callbacks->setEmittedTokensOnThisLine();
876 if (ShouldExpandTokens) {
879 auto Toks = std::make_unique<Token[]>(1);
881 PP.EnterTokenStream(std::move(Toks), 1,
889 while (PragmaTok.
isNot(tok::eod)) {
890 Callbacks->HandleWhitespaceBeforeTok(PragmaTok, IsFirst,
894 Callbacks->OS->write(&TokSpell[0], TokSpell.size());
895 Callbacks->setEmittedTokensOnThisLine();
897 if (ShouldExpandTokens)
902 Callbacks->setEmittedDirectiveOnThisLine();
909 PrintPPOutputPPCallbacks *Callbacks) {
915 StringRef FooterContentBuffer = SourceMgr.
getBufferData(FooterFileID);
917 Callbacks->WriteFooterInfo(Footer);
919 FooterContentBuffer.split(FooterContentArr,
'\r');
921 for (
auto &Val : FooterContentArr) {
922 Val.consume_front(
"\n");
924 Callbacks->WriteFooterContent(Val);
929 PrintPPOutputPPCallbacks *Callbacks) {
930 bool DropComments = PP.
getLangOpts().TraditionalCPP &&
933 bool IsStartOfLine =
false;
945 Callbacks->HandleWhitespaceBeforeTok(Tok,
false,
948 if (DropComments && Tok.
is(tok::comment)) {
954 }
else if (Tok.
is(tok::annot_repl_input_end)) {
957 }
else if (Tok.
is(tok::eod)) {
964 IsStartOfLine =
true;
966 }
else if (Tok.
is(tok::annot_module_include)) {
970 IsStartOfLine =
true;
972 }
else if (Tok.
is(tok::annot_module_begin)) {
979 Callbacks->BeginModule(
982 IsStartOfLine =
true;
984 }
else if (Tok.
is(tok::annot_module_end)) {
985 Callbacks->EndModule(
988 IsStartOfLine =
true;
990 }
else if (Tok.
is(tok::annot_header_unit)) {
997 Callbacks->OS->write(Name.data(), Name.size());
998 Callbacks->HandleNewlinesInToken(Name.data(), Name.size());
999 }
else if (Tok.
is(tok::annot_embed)) {
1004 assert(Callbacks->expandEmbedContents() &&
1005 "did not expect an embed annotation");
1011 bool PrintComma =
false;
1012 for (
auto Iter =
Data->BinaryData.begin(),
End =
Data->BinaryData.end();
1015 *Callbacks->OS <<
", ";
1016 *Callbacks->OS <<
static_cast<unsigned>(*Iter);
1025 *Callbacks->OS << II->getName();
1029 }
else if (Tok.
getLength() < std::size(Buffer)) {
1030 const char *TokPtr = Buffer;
1032 Callbacks->OS->write(TokPtr, Len);
1039 if (Tok.
getKind() == tok::comment || Tok.
getKind() == tok::unknown)
1040 Callbacks->HandleNewlinesInToken(TokPtr, Len);
1041 if (Tok.
is(tok::comment) && Len >= 2 && TokPtr[0] ==
'/' &&
1045 Callbacks->setEmittedDirectiveOnThisLine();
1049 Callbacks->OS->write(S.data(), S.size());
1053 if (Tok.
getKind() == tok::comment || Tok.
getKind() == tok::unknown)
1054 Callbacks->HandleNewlinesInToken(S.data(), S.size());
1055 if (Tok.
is(tok::comment) && S.size() >= 2 && S[0] ==
'/' && S[1] ==
'/') {
1058 Callbacks->setEmittedDirectiveOnThisLine();
1061 Callbacks->setEmittedTokensOnThisLine();
1062 IsStartOfLine =
false;
1068 for (
unsigned I = 0, Skip = Callbacks->GetNumToksToSkip(); I < Skip; ++I)
1070 Callbacks->ResetSkipToks();
1076 return LHS->first->getName().compare(RHS->first->getName());
1094 auto *MD = I->second.getLatest();
1095 if (MD && MD->isDefined())
1098 llvm::array_pod_sort(MacrosByID.begin(), MacrosByID.end(),
MacroIDCompare);
1100 for (
unsigned i = 0, e = MacrosByID.size(); i != e; ++i) {
1116 assert(Opts.
ShowMacros &&
"Not yet implemented!");
1125 PrintPPOutputPPCallbacks *Callbacks =
new PrintPPOutputPPCallbacks(
1134 std::unique_ptr<UnknownPragmaHandler> MicrosoftExtHandler(
1135 new UnknownPragmaHandler(
1136 "#pragma", Callbacks,
1139 std::unique_ptr<UnknownPragmaHandler> GCCHandler(
new UnknownPragmaHandler(
1140 "#pragma GCC", Callbacks,
1143 std::unique_ptr<UnknownPragmaHandler> ClangHandler(
new UnknownPragmaHandler(
1144 "#pragma clang", Callbacks,
1156 std::unique_ptr<UnknownPragmaHandler> OpenMPHandler(
1157 new UnknownPragmaHandler(
"#pragma omp", Callbacks,
1193 "The 'include-footer' is expected in host compilation only");
Defines the Diagnostic-related interfaces.
enum clang::sema::@1659::IndirectLocalPathEntry::EntryKind Kind
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 void PrintIncludeFooter(Preprocessor &PP, SourceLocation Loc, std::string Footer, PrintPPOutputPPCallbacks *Callbacks)
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
bool isGNUVarargs() const
ArrayRef< Token > tokens() 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.
PragmaHandler - Instances of this interface defined to handle the various pragmas that the language f...
std::string IncludeFooter
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.
PreprocessorOptions & getPreprocessorOpts() const
Retrieve the preprocessor options used to initialize this preprocessor.
void IgnorePragmas()
Install empty handlers for all pragmas (making them ignored).
SourceManager & getSourceManager() const
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
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.
bool IncludeFooterProcessed
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.
StringRef getBufferData(FileID FID, bool *Invalid=nullptr) const
Return a StringRef to the source buffer data for the specified FileID.
FileID ComputeValidFooterFileID(StringRef Footer)
Get the file ID for the integration footer.
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.
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
void * getAnnotationValue() 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)) {....
const char * getLiteralData() const
getLiteralData - For a literal token (numeric constant, string, etc), this returns a pointer to the s...
tok::TokenKind getKind() const
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
IdentifierInfo * getIdentifierInfo() const
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.
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),...
@ Warning
Present this diagnostic as a warning.
@ Fatal
Present this diagnostic as a fatal error.
@ Error
Present this diagnostic as an error.
@ Remark
Present this diagnostic as a remark.
@ Ignored
Do not present this diagnostic, ignore it.
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.