55#include "llvm/ADT/APInt.h"
56#include "llvm/ADT/ArrayRef.h"
57#include "llvm/ADT/DenseMap.h"
58#include "llvm/ADT/STLExtras.h"
59#include "llvm/ADT/ScopeExit.h"
60#include "llvm/ADT/SmallVector.h"
61#include "llvm/ADT/StringRef.h"
62#include "llvm/Support/Capacity.h"
63#include "llvm/Support/ErrorHandling.h"
64#include "llvm/Support/MemoryBuffer.h"
65#include "llvm/Support/MemoryBufferRef.h"
66#include "llvm/Support/SaveAndRestore.h"
67#include "llvm/Support/raw_ostream.h"
91 : PPOpts(PPOpts), Diags(&diags), LangOpts(opts),
92 FileMgr(Headers.getFileMgr()), SourceMgr(
SM),
93 ScratchBuf(new
ScratchBuffer(SourceMgr)), HeaderInfo(Headers),
94 TheModuleLoader(TheModuleLoader), ExternalSource(
nullptr),
98 Identifiers(IILookup), PragmaHandlers(new
PragmaNamespace(StringRef())),
100 CurSubmoduleState(&NullSubmoduleState) {
101 OwnsHeaderSearch = OwnsHeaders;
104 KeepComments =
false;
105 KeepMacroComments =
false;
106 SuppressIncludeNotFoundError =
false;
109 DisableMacroExpansion =
false;
110 MacroExpansionInDirectivesOverride =
false;
113 InMacroArgPreExpansion =
false;
114 NumCachedTokenLexers = 0;
115 PragmasEnabled =
true;
116 ParsingIfOrElifDirective =
false;
117 PreprocessedOutput =
false;
120 ReadMacrosFromExternalSource =
false;
122 LastExportKeyword.startToken();
124 BuiltinInfo = std::make_unique<Builtin::Context>();
134 RegisterBuiltinPragmas();
137 RegisterBuiltinMacros();
139 if(LangOpts.Borland) {
150 Ident__exception_info = Ident__exception_code =
nullptr;
151 Ident__abnormal_termination = Ident___exception_info =
nullptr;
152 Ident___exception_code = Ident___abnormal_termination =
nullptr;
153 Ident_GetExceptionInfo = Ident_GetExceptionCode =
nullptr;
154 Ident_AbnormalTermination =
nullptr;
159 IncrementalProcessing = LangOpts.IncrementalExtensions;
163 SkippingUntilPragmaHdrStop =
true;
167 !this->PPOpts.ImplicitPCHInclude.empty())
168 SkippingUntilPCHThroughHeader =
true;
171 PreambleConditionalStack.startRecording();
173 MaxTokens = LangOpts.MaxTokens;
179 IncludeMacroStack.clear();
184 std::fill(TokenLexerCache, TokenLexerCache + NumCachedTokenLexers,
nullptr);
185 CurTokenLexer.reset();
188 for (
MacroArgs *ArgList = MacroArgCache; ArgList;)
189 ArgList = ArgList->deallocate();
192 if (OwnsHeaderSearch)
198 assert((!this->Target || this->Target == &Target) &&
199 "Invalid override of target information");
200 this->Target = &Target;
202 assert((!this->AuxTarget || this->AuxTarget == AuxTarget) &&
203 "Invalid override of aux target information.");
204 this->AuxTarget = AuxTarget;
207 BuiltinInfo->InitializeTarget(Target, AuxTarget);
208 HeaderInfo.setTarget(Target);
211 Identifiers.AddKeywords(LangOpts);
225 NumEnteredSourceFiles = 0;
228 PragmaHandlersBackup = std::move(PragmaHandlers);
229 PragmaHandlers = std::make_unique<PragmaNamespace>(StringRef());
230 RegisterBuiltinPragmas();
233 PredefinesFileID =
FileID();
237 NumEnteredSourceFiles = 1;
239 PragmaHandlers = std::move(PragmaHandlersBackup);
245 if (!
Tok.isAnnotation())
248 if (!DumpFlags)
return;
250 llvm::errs() <<
"\t";
251 if (
Tok.isAtStartOfLine())
252 llvm::errs() <<
" [StartOfLine]";
253 if (
Tok.hasLeadingSpace())
254 llvm::errs() <<
" [LeadingSpace]";
255 if (
Tok.isExpandDisabled())
256 llvm::errs() <<
" [ExpandDisabled]";
257 if (
Tok.needsCleaning()) {
258 const char *Start = SourceMgr.getCharacterData(
Tok.getLocation());
259 llvm::errs() <<
" [UnClean='" << StringRef(Start,
Tok.getLength())
263 llvm::errs() <<
"\tLoc=<";
269 Loc.
print(llvm::errs(), SourceMgr);
273 llvm::errs() <<
"MACRO: ";
274 for (
unsigned i = 0, e = MI.
getNumTokens(); i != e; ++i) {
278 llvm::errs() <<
"\n";
282 llvm::errs() <<
"\n*** Preprocessor Stats:\n";
283 llvm::errs() << NumDirectives <<
" directives found:\n";
284 llvm::errs() <<
" " << NumDefined <<
" #define.\n";
285 llvm::errs() <<
" " << NumUndefined <<
" #undef.\n";
286 llvm::errs() <<
" #include/#include_next/#import:\n";
287 llvm::errs() <<
" " << NumEnteredSourceFiles <<
" source files entered.\n";
288 llvm::errs() <<
" " << MaxIncludeStackDepth <<
" max include stack depth\n";
289 llvm::errs() <<
" " << NumIf <<
" #if/#ifndef/#ifdef.\n";
290 llvm::errs() <<
" " << NumElse <<
" #else/#elif/#elifdef/#elifndef.\n";
291 llvm::errs() <<
" " << NumEndif <<
" #endif.\n";
292 llvm::errs() <<
" " << NumPragma <<
" #pragma.\n";
293 llvm::errs() << NumSkipped <<
" #if/#ifndef#ifdef regions skipped\n";
295 llvm::errs() << NumMacroExpanded <<
"/" << NumFnMacroExpanded <<
"/"
296 << NumBuiltinMacroExpanded <<
" obj/fn/builtin macros expanded, "
297 << NumFastMacroExpanded <<
" on the fast path.\n";
298 llvm::errs() << (NumFastTokenPaste+NumTokenPaste)
299 <<
" token paste (##) operations performed, "
300 << NumFastTokenPaste <<
" on the fast path.\n";
302 llvm::errs() <<
"\nPreprocessor Memory: " <<
getTotalMemory() <<
"B total";
304 llvm::errs() <<
"\n BumpPtr: " << BP.getTotalMemory();
305 llvm::errs() <<
"\n Macro Expanded Tokens: "
306 << llvm::capacity_in_bytes(MacroExpandedTokens);
307 llvm::errs() <<
"\n Predefines Buffer: " << Predefines.capacity();
309 llvm::errs() <<
"\n Macros: "
310 << llvm::capacity_in_bytes(CurSubmoduleState->Macros);
311 llvm::errs() <<
"\n #pragma push_macro Info: "
312 << llvm::capacity_in_bytes(PragmaPushMacroInfo);
313 llvm::errs() <<
"\n Poison Reasons: "
314 << llvm::capacity_in_bytes(PoisonReasons);
315 llvm::errs() <<
"\n Comment Handlers: "
316 << llvm::capacity_in_bytes(CommentHandlers) <<
"\n";
321 if (IncludeExternalMacros && ExternalSource &&
322 !ReadMacrosFromExternalSource) {
323 ReadMacrosFromExternalSource =
true;
324 ExternalSource->ReadDefinedMacros();
329 CurSubmoduleState->Macros.try_emplace(
Macro.II);
331 return CurSubmoduleState->Macros.begin();
335 return BP.getTotalMemory()
336 + llvm::capacity_in_bytes(MacroExpandedTokens)
337 + Predefines.capacity()
340 + llvm::capacity_in_bytes(CurSubmoduleState->Macros)
341 + llvm::capacity_in_bytes(PragmaPushMacroInfo)
342 + llvm::capacity_in_bytes(PoisonReasons)
343 + llvm::capacity_in_bytes(CommentHandlers);
348 if (IncludeExternalMacros && ExternalSource &&
349 !ReadMacrosFromExternalSource) {
350 ReadMacrosFromExternalSource =
true;
351 ExternalSource->ReadDefinedMacros();
354 return CurSubmoduleState->Macros.end();
361 std::equal(Tokens.begin(), Tokens.end(), MI->
tokens_begin());
368 StringRef BestSpelling;
372 Def = I->second.findDirectiveAtLoc(Loc, SourceMgr);
382 (Location.isValid() &&
383 SourceMgr.isBeforeInTranslationUnit(BestLocation, Location))) {
384 BestLocation = Location;
385 BestSpelling = I->first->getName();
393 CurLexerCallback = CurLexer->isDependencyDirectivesLexer()
394 ? CLK_DependencyDirectivesLexer
396 else if (CurTokenLexer)
397 CurLexerCallback = CLK_TokenLexer;
399 CurLexerCallback = CLK_CachingLexer;
403 unsigned CompleteLine,
404 unsigned CompleteColumn) {
405 assert(CompleteLine && CompleteColumn &&
"Starts from 1:1");
406 assert(!CodeCompletionFile &&
"Already set");
409 std::optional<llvm::MemoryBufferRef> Buffer =
410 SourceMgr.getMemoryBufferForFileOrNone(
File);
415 const char *Position = Buffer->getBufferStart();
417 for (; *Position; ++Position) {
418 if (*Position !=
'\r' && *Position !=
'\n')
422 if ((Position[1] ==
'\r' || Position[1] ==
'\n') &&
423 Position[0] != Position[1])
430 Position += CompleteColumn - 1;
434 if (SkipMainFilePreamble.first &&
435 SourceMgr.getFileEntryForID(SourceMgr.getMainFileID()) ==
File) {
436 if (Position - Buffer->getBufferStart() < SkipMainFilePreamble.first)
437 Position = Buffer->getBufferStart() + SkipMainFilePreamble.first;
440 if (Position > Buffer->getBufferEnd())
441 Position = Buffer->getBufferEnd();
443 CodeCompletionFile =
File;
444 CodeCompletionOffset = Position - Buffer->getBufferStart();
446 auto NewBuffer = llvm::WritableMemoryBuffer::getNewUninitMemBuffer(
447 Buffer->getBufferSize() + 1, Buffer->getBufferIdentifier());
448 char *NewBuf = NewBuffer->getBufferStart();
449 char *NewPos = std::copy(Buffer->getBufferStart(), Position, NewBuf);
451 std::copy(Position, Buffer->getBufferEnd(), NewPos+1);
452 SourceMgr.overrideFileContents(
File, std::move(NewBuffer));
461 CodeComplete->CodeCompleteIncludedFile(Dir, IsAngled);
467 CodeComplete->CodeCompleteNaturalLanguage();
477 if (
Tok.isNot(tok::raw_identifier) && !
Tok.hasUCN()) {
480 return II->getName();
484 if (
Tok.needsCleaning())
485 Buffer.resize(
Tok.getLength());
487 const char *Ptr = Buffer.data();
489 return StringRef(Ptr, Len);
498 Tok.setLength(Str.size());
501 SourceLocation Loc = ScratchBuf->getToken(Str.data(), Str.size(), DestPtr);
503 if (ExpansionLocStart.
isValid())
504 Loc = SourceMgr.createExpansionLoc(Loc, ExpansionLocStart,
505 ExpansionLocEnd, Str.size());
506 Tok.setLocation(Loc);
509 if (
Tok.is(tok::raw_identifier))
510 Tok.setRawIdentifierData(DestPtr);
511 else if (
Tok.isLiteral())
512 Tok.setLiteralData(DestPtr);
520 StringRef Buffer =
SM.getBufferData(LocInfo.first, &
Invalid);
527 ScratchBuf->getToken(Buffer.data() + LocInfo.second, Length, DestPtr);
539 if (!
getLangOpts().isCompilingModuleImplementation())
555 assert(NumEnteredSourceFiles == 0 &&
"Cannot reenter the main file!");
556 FileID MainFileID = SourceMgr.getMainFileID();
560 if (!SourceMgr.isLoadedFileID(MainFileID)) {
566 if (SkipMainFilePreamble.first > 0)
567 CurLexer->SetByteOffset(SkipMainFilePreamble.first,
568 SkipMainFilePreamble.second);
585 std::optional<StringRef> Input =
588 MainFileIsPreprocessedModuleFile =
590 auto Tracer = std::make_unique<NoTrivialPPDirectiveTracer>(*
this);
591 DirTracer = Tracer.get();
593 std::optional<Token> FirstPPTok = CurLexer->peekNextPPToken();
595 FirstPPTokenLoc = FirstPPTok->getLocation();
600 std::unique_ptr<llvm::MemoryBuffer> SB =
601 llvm::MemoryBuffer::getMemBufferCopy(Predefines,
"<built-in>");
602 assert(SB &&
"Cannot create predefined source buffer");
603 FileID FID = SourceMgr.createFileID(std::move(SB));
604 assert(FID.
isValid() &&
"Could not create FileID for predefines?");
605 setPredefinesFileID(FID);
610 if (!PPOpts.PCHThroughHeader.empty()) {
615 false,
nullptr,
nullptr,
616 nullptr,
nullptr,
nullptr,
621 << PPOpts.PCHThroughHeader;
624 setPCHThroughHeaderFileID(
634void Preprocessor::setPCHThroughHeaderFileID(
FileID FID) {
635 assert(PCHThroughHeaderFileID.
isInvalid() &&
636 "PCHThroughHeaderFileID already set!");
637 PCHThroughHeaderFileID = FID;
641 assert(PCHThroughHeaderFileID.isValid() &&
642 "Invalid PCH through header FileID");
643 return FE == SourceMgr.getFileEntryForID(PCHThroughHeaderFileID);
648 PCHThroughHeaderFileID.isValid();
653 PCHThroughHeaderFileID.isValid();
670 bool ReachedMainFileEOF =
false;
671 bool UsingPCHThroughHeader = SkippingUntilPCHThroughHeader;
672 bool UsingPragmaHdrStop = SkippingUntilPragmaHdrStop;
677 CurLexerCallback(*
this,
Tok);
678 if (
Tok.is(tok::eof) && !InPredefines) {
679 ReachedMainFileEOF =
true;
682 if (UsingPCHThroughHeader && !SkippingUntilPCHThroughHeader)
684 if (UsingPragmaHdrStop && !SkippingUntilPragmaHdrStop)
687 if (ReachedMainFileEOF) {
688 if (UsingPCHThroughHeader)
690 << PPOpts.PCHThroughHeader << 1;
691 else if (!PPOpts.PCHWithHdrStopCreate)
696void Preprocessor::replayPreambleConditionalStack() {
698 if (PreambleConditionalStack.isReplaying()) {
700 "CurPPLexer is null when calling replayPreambleConditionalStack.");
702 PreambleConditionalStack.doneReplaying();
703 if (PreambleConditionalStack.reachedEOFWhileSkipping())
704 SkipExcludedConditionalBlock(
705 PreambleConditionalStack.SkipInfo->HashTokenLoc,
706 PreambleConditionalStack.SkipInfo->IfTokenLoc,
707 PreambleConditionalStack.SkipInfo->FoundNonSkipPortion,
708 PreambleConditionalStack.SkipInfo->FoundElse,
709 PreambleConditionalStack.SkipInfo->ElseLoc);
716 Callbacks->EndOfMainFile();
727 assert(!Identifier.
getRawIdentifier().empty() &&
"No raw identifier data!");
737 StringRef CleanedStr =
getSpelling(Identifier, IdentifierBuffer);
739 if (Identifier.
hasUCN()) {
762 PoisonReasons[II] = DiagID;
766 assert(Ident__exception_code && Ident__exception_info);
767 assert(Ident___exception_code && Ident___exception_info);
768 Ident__exception_code->setIsPoisoned(Poison);
769 Ident___exception_code->setIsPoisoned(Poison);
770 Ident_GetExceptionCode->setIsPoisoned(Poison);
771 Ident__exception_info->setIsPoisoned(Poison);
772 Ident___exception_info->setIsPoisoned(Poison);
773 Ident_GetExceptionInfo->setIsPoisoned(Poison);
774 Ident__abnormal_termination->setIsPoisoned(Poison);
775 Ident___abnormal_termination->setIsPoisoned(Poison);
776 Ident_AbnormalTermination->setIsPoisoned(Poison);
781 "Can't handle identifiers without identifier info!");
782 llvm::DenseMap<IdentifierInfo*,unsigned>::const_iterator it =
784 if(it == PoisonReasons.end())
785 Diag(Identifier, diag::err_pp_used_poisoned_id);
790void Preprocessor::updateOutOfDateIdentifier(
const IdentifierInfo &II)
const {
793 "getExternalSource() should not return nullptr");
807 "Can't handle identifiers without identifier info!");
817 bool CurrentIsPoisoned =
false;
818 const bool IsSpecialVariadicMacro =
819 &II == Ident__VA_ARGS__ || &II == Ident__VA_OPT__;
820 if (IsSpecialVariadicMacro)
823 updateOutOfDateIdentifier(II);
826 if (IsSpecialVariadicMacro)
838 const auto *MI = MD.getMacroInfo();
839 assert(MI &&
"macro definition with no macro info?");
840 if (!DisableMacroExpansion) {
845 return HandleMacroExpandedIdentifier(Identifier, MD);
852 Diag(Identifier, diag::pp_disabled_macro_expansion);
872 Diag(Identifier, diag::warn_pp_identifier_is_cpp_keyword) << &II;
879 Diag(Identifier, diag::ext_token_used);
883 !CurLexer->isLexingRawMode() && !CurLexer->isPragmaLexer() &&
884 !CurLexer->ParsingPreprocessorDirective &&
901 Identifier.
is(tok::kw_import)) &&
903 (!DisableMacroExpansion || MacroExpansionInDirectivesOverride) &&
904 CurLexerCallback != CLK_CachingLexer) {
907 CurLexerCallback = CLK_LexAfterModuleImport;
916 while (!CurLexerCallback(*
this,
Result))
919 if (
Result.is(tok::unknown) && TheModuleLoader.HadFatalFailure)
922 if (
Result.is(tok::code_completion) &&
Result.getIdentifierInfo()) {
928 Result.setIdentifierInfo(
nullptr);
936 if (
getLangOpts().CPlusPlusModules && LexLevel == 1 &&
938 switch (
Result.getKind()) {
939 case tok::l_paren:
case tok::l_square:
case tok::l_brace:
940 StdCXXImportSeqState.handleOpenBracket();
942 case tok::r_paren:
case tok::r_square:
943 StdCXXImportSeqState.handleCloseBracket();
946 StdCXXImportSeqState.handleCloseBrace();
948#define PRAGMA_ANNOTATION(X) case tok::annot_##X:
950#include "clang/Basic/TokenKinds.def"
951#undef PRAGMA_ANNOTATION
954 case tok::annot_module_include:
955 case tok::annot_repl_input_end:
957 TrackGMFState.handleSemi();
958 StdCXXImportSeqState.handleSemi();
959 ModuleDeclState.handleSemi();
961 case tok::header_name:
962 case tok::annot_header_unit:
963 StdCXXImportSeqState.handleHeaderName();
968 TrackGMFState.handleExport();
969 StdCXXImportSeqState.handleExport();
970 ModuleDeclState.handleExport();
973 ModuleDeclState.handleColon();
976 if (StdCXXImportSeqState.atTopLevel()) {
977 TrackGMFState.handleImport(StdCXXImportSeqState.afterTopLevelSeq());
978 StdCXXImportSeqState.handleImport();
982 if (StdCXXImportSeqState.atTopLevel()) {
985 TrackGMFState.handleModule(StdCXXImportSeqState.afterTopLevelSeq());
986 ModuleDeclState.handleModule();
989 case tok::annot_module_name:
990 ModuleDeclState.handleModuleName(
992 if (ModuleDeclState.isModuleCandidate())
996 TrackGMFState.handleMisc();
997 StdCXXImportSeqState.handleMisc();
998 ModuleDeclState.handleMisc();
1004 CheckPoints[CurLexer->getFileID()].push_back(CurLexer->BufferPtr);
1005 CheckPointCounter = 0;
1008 LastTokenWasAt =
Result.is(tok::at);
1009 if (
Result.isNot(tok::kw_export))
1010 LastExportKeyword.startToken();
1017 if (LexLevel == 0 && !PendingDestroyLexers.empty())
1018 PendingDestroyLexers.clear();
1020 if ((LexLevel == 0 || PreprocessToken) &&
1033 if (
Tok.isOneOf(tok::unknown, tok::eof, tok::eod,
1034 tok::annot_repl_input_end))
1036 if (Tokens !=
nullptr)
1037 Tokens->push_back(
Tok);
1058 if (CurPPLexer->ParsingFilename)
1061 CurPPLexer->LexIncludeFilename(FilenameTok);
1069 if (FilenameTok.
is(tok::less) && AllowMacroExpansion) {
1076 FilenameBuffer.push_back(
'<');
1082 while (FilenameTok.
isNot(tok::greater)) {
1084 if (FilenameTok.
isOneOf(tok::eod, tok::eof)) {
1086 Diag(Start, diag::note_matching) << tok::less;
1093 if (FilenameTok.
is(tok::code_completion)) {
1102 FilenameBuffer.push_back(
' ');
1106 size_t PreAppendSize = FilenameBuffer.size();
1107 FilenameBuffer.resize(PreAppendSize + FilenameTok.
getLength());
1109 const char *BufPtr = &FilenameBuffer[PreAppendSize];
1110 unsigned ActualLen =
getSpelling(FilenameTok, BufPtr);
1113 if (BufPtr != &FilenameBuffer[PreAppendSize])
1114 memcpy(&FilenameBuffer[PreAppendSize], BufPtr, ActualLen);
1117 if (FilenameTok.
getLength() != ActualLen)
1118 FilenameBuffer.resize(PreAppendSize + ActualLen);
1122 FilenameTok.
setKind(tok::header_name);
1127 }
else if (FilenameTok.
is(tok::string_literal) && AllowMacroExpansion) {
1138 StringRef Str =
getSpelling(FilenameTok, FilenameBuffer);
1139 if (Str.size() >= 2 && Str.front() ==
'"' && Str.back() ==
'"')
1140 FilenameTok.
setKind(tok::header_name);
1146std::optional<Token> Preprocessor::peekNextPPToken()
const {
1148 std::optional<Token> Val;
1150 Val = CurLexer->peekNextPPToken();
1152 Val = CurTokenLexer->peekNextPPToken();
1159 return std::nullopt;
1160 for (
const IncludeStackInfo &Entry : llvm::reverse(IncludeMacroStack)) {
1162 Val = Entry.TheLexer->peekNextPPToken();
1164 Val = Entry.TheTokenLexer->peekNextPPToken();
1170 if (Entry.ThePPLexer)
1171 return std::nullopt;
1189 for (
auto &Piece : Path) {
1190 assert(Piece.getIdentifierInfo() && Piece.getLoc().isValid());
1193 Name += Piece.getIdentifierInfo()->getName();
1199 assert(!Path.empty() &&
"expect at least one identifier in a module name");
1201 totalSizeToAlloc<IdentifierLoc>(Path.size()),
alignof(ModuleNameLoc));
1202 return new (Mem) ModuleNameLoc(Path);
1208 bool AllowMacroExpansion,
1210 auto ConsumeToken = [&]() {
1211 if (AllowMacroExpansion)
1215 Suffix.push_back(
Tok);
1219 if (
Tok.isNot(tok::identifier)) {
1220 if (
Tok.is(tok::code_completion)) {
1221 CurLexer->cutOffLexing();
1222 CodeComplete->CodeCompleteModuleImport(UseLoc, Path);
1226 Diag(
Tok, diag::err_pp_module_expected_ident) << Path.empty();
1235 !AllowMacroExpansion) {
1236 Diag(
Tok, diag::err_pp_module_name_is_macro)
1237 << IsPartition <<
Tok.getIdentifierInfo();
1238 Diag(MI->getDefinitionLoc(), diag::note_macro_here)
1239 <<
Tok.getIdentifierInfo();
1243 Path.emplace_back(
Tok.getLocation(),
Tok.getIdentifierInfo());
1246 if (
Tok.isNot(tok::period))
1282 if (
Result.is(tok::kw_export)) {
1283 LastExportKeyword =
Result;
1296 if (LastExportKeyword.is(tok::kw_export)) {
1299 if (!LastExportKeyword.isAtPhysicalStartOfLine())
1304 if (
Result.isAtPhysicalStartOfLine())
1306 }
else if (!
Result.isAtPhysicalStartOfLine())
1310 CurPPLexer->ParsingPreprocessorDirective,
true);
1314 CurPPLexer->ParsingFilename,
1315 Result.getIdentifierInfo()->isImportKeyword());
1317 std::optional<Token> NextTok =
1318 CurLexer ? CurLexer->peekNextPPToken() : CurTokenLexer->peekNextPPToken();
1322 if (NextTok->is(tok::raw_identifier))
1325 if (
Result.getIdentifierInfo()->isImportKeyword()) {
1326 if (NextTok->isOneOf(tok::identifier, tok::less, tok::colon,
1327 tok::header_name)) {
1328 Result.setKind(tok::kw_import);
1329 ModuleImportLoc =
Result.getLocation();
1335 if (
Result.getIdentifierInfo()->isModuleKeyword() &&
1336 NextTok->isOneOf(tok::identifier, tok::colon, tok::semi)) {
1337 Result.setKind(tok::kw_module);
1338 ModuleDeclLoc =
Result.getLocation();
1355 bool StopUntilEOD) {
1357 Toks.emplace_back();
1360 switch (Toks.back().getKind()) {
1379 auto ToksCopy = std::make_unique<Token[]>(Toks.size());
1380 std::copy(Toks.begin(), Toks.end(), ToksCopy.get());
1381 EnterTokenStream(std::move(ToksCopy), Toks.size(),
1383 assert(CurTokenLexer &&
"Must have a TokenLexer");
1384 CurTokenLexer->setLexingCXXModuleDirective();
1418 Suffix.emplace_back();
1419 Suffix.back().setKind(tok::annot_module_name);
1420 Suffix.back().setAnnotationRange(NameLoc->
getRange());
1421 Suffix.back().setAnnotationValue(
static_cast<void *
>(NameLoc));
1422 Suffix.push_back(
Result);
1427 if (Suffix.back().isNot(tok::semi)) {
1428 if (Suffix.back().isNot(tok::eof))
1430 if (Suffix.back().isNot(tok::semi)) {
1435 SemiLoc = Suffix.back().getLocation();
1438 Module *Imported =
nullptr;
1440 Imported = TheModuleLoader.loadModule(ModuleImportLoc, Path,
Module::Hidden,
1447 Callbacks->moduleImport(ModuleImportLoc, Path, Imported);
1449 if (!Suffix.empty()) {
1457 bool IncludeExports) {
1458 CurSubmoduleState->VisibleModules.setVisible(
1459 M, Loc, IncludeExports, [](
Module *) {},
1463 Diag(ModuleImportLoc, diag::warn_module_conflict)
1464 << Path[0]->getFullModuleName()
1465 << Conflict->getFullModuleName()
1470 if (!BuildingSubmoduleStack.empty() && M != BuildingSubmoduleStack.back().M)
1471 BuildingSubmoduleStack.back().M->
Imports.insert(M);
1475 const char *DiagnosticTag,
1476 bool AllowMacroExpansion) {
1478 if (
Result.isNot(tok::string_literal)) {
1479 Diag(
Result, diag::err_expected_string_literal)
1480 << 0 << DiagnosticTag;
1487 StrToks.push_back(
Result);
1489 if (
Result.hasUDSuffix())
1492 if (AllowMacroExpansion)
1496 }
while (
Result.is(tok::string_literal));
1500 assert(Literal.isOrdinary() &&
"Didn't allow wide strings in");
1502 if (Literal.hadError)
1505 if (Literal.Pascal) {
1506 Diag(StrToks[0].getLocation(), diag::err_expected_string_literal)
1507 << 0 << DiagnosticTag;
1511 String = std::string(Literal.GetString());
1516 assert(
Tok.is(tok::numeric_constant));
1518 bool NumberInvalid =
false;
1519 StringRef Spelling =
getSpelling(
Tok, IntegerBuffer, &NumberInvalid);
1525 if (Literal.hadError || !Literal.isIntegerLiteral() || Literal.hasUDSuffix())
1527 llvm::APInt APVal(64, 0);
1528 if (Literal.GetIntegerValue(APVal))
1531 Value = APVal.getLimitedValue();
1536 assert(Handler &&
"NULL comment handler");
1537 assert(!llvm::is_contained(CommentHandlers, Handler) &&
1538 "Comment handler already registered");
1539 CommentHandlers.push_back(Handler);
1543 std::vector<CommentHandler *>::iterator Pos =
1544 llvm::find(CommentHandlers, Handler);
1545 assert(Pos != CommentHandlers.end() &&
"Comment handler not registered");
1546 CommentHandlers.erase(Pos);
1550 bool AnyPendingTokens =
false;
1552 if (H->HandleComment(*
this, Comment))
1553 AnyPendingTokens =
true;
1561void Preprocessor::emitMacroDeprecationWarning(
const Token &Identifier)
const {
1562 const MacroAnnotations &A =
1564 assert(A.DeprecationInfo &&
1565 "Macro deprecation warning without recorded annotation!");
1566 const MacroAnnotationInfo &Info = *A.DeprecationInfo;
1567 if (Info.Message.empty())
1568 Diag(Identifier, diag::warn_pragma_deprecated_macro_use)
1571 Diag(Identifier, diag::warn_pragma_deprecated_macro_use)
1573 Diag(Info.Location, diag::note_pp_macro_annotation) << 0;
1576void Preprocessor::emitRestrictExpansionWarning(
const Token &Identifier)
const {
1577 const MacroAnnotations &A =
1579 assert(A.RestrictExpansionInfo &&
1580 "Macro restricted expansion warning without recorded annotation!");
1581 const MacroAnnotationInfo &Info = *A.RestrictExpansionInfo;
1582 if (Info.Message.empty())
1583 Diag(Identifier, diag::warn_pragma_restrict_expansion_macro_use)
1586 Diag(Identifier, diag::warn_pragma_restrict_expansion_macro_use)
1588 Diag(Info.Location, diag::note_pp_macro_annotation) << 1;
1591void Preprocessor::emitRestrictInfNaNWarning(
const Token &Identifier,
1592 unsigned DiagSelection)
const {
1593 Diag(Identifier, diag::warn_fp_nan_inf_when_disabled) << DiagSelection << 1;
1596void Preprocessor::emitFinalMacroWarning(
const Token &Identifier,
1597 bool IsUndef)
const {
1598 const MacroAnnotations &A =
1600 assert(A.FinalAnnotationLoc &&
1601 "Final macro warning without recorded annotation!");
1603 Diag(Identifier, diag::warn_pragma_final_macro)
1605 Diag(*A.FinalAnnotationLoc, diag::note_pp_macro_annotation) << 2;
1612 auto TestInMap = [&SourceMgr](
const SafeBufferOptOutRegionsTy &Map,
1615 auto FirstRegionEndingAfterLoc = llvm::partition_point(
1617 &Loc](
const std::pair<SourceLocation, SourceLocation> &Region) {
1618 return SourceMgr.isBeforeInTranslationUnit(Region.second, Loc);
1621 if (FirstRegionEndingAfterLoc != Map.end()) {
1623 return SourceMgr.isBeforeInTranslationUnit(
1624 FirstRegionEndingAfterLoc->first, Loc);
1628 if (!Map.empty() && Map.back().first == Map.back().second)
1629 return SourceMgr.isBeforeInTranslationUnit(Map.back().first, Loc);
1651 if (SourceMgr.isLocalSourceLocation(Loc))
1652 return TestInMap(SafeBufferOptOutMap, Loc);
1655 LoadedSafeBufferOptOutMap.lookupLoadedOptOutMap(Loc, SourceMgr);
1667 InSafeBufferOptOutRegion =
true;
1668 CurrentSafeBufferOptOutStart = Loc;
1672 if (!SafeBufferOptOutMap.empty()) {
1673 [[maybe_unused]]
auto *PrevRegion = &SafeBufferOptOutMap.back();
1674 assert(PrevRegion->first != PrevRegion->second &&
1675 "Shall not begin a safe buffer opt-out region before closing the "
1681 SafeBufferOptOutMap.emplace_back(Loc, Loc);
1685 InSafeBufferOptOutRegion =
false;
1689 assert(!SafeBufferOptOutMap.empty() &&
1690 "Misordered safe buffer opt-out regions");
1691 auto *CurrRegion = &SafeBufferOptOutMap.back();
1692 assert(CurrRegion->first == CurrRegion->second &&
1693 "Set end location to a closed safe buffer opt-out region");
1694 CurrRegion->second = Loc;
1700 return InSafeBufferOptOutRegion;
1703 StartLoc = CurrentSafeBufferOptOutStart;
1704 return InSafeBufferOptOutRegion;
1709 assert(!InSafeBufferOptOutRegion &&
1710 "Attempt to serialize safe buffer opt-out regions before file being "
1711 "completely preprocessed");
1715 for (
const auto &[begin, end] : SafeBufferOptOutMap) {
1716 SrcSeq.push_back(begin);
1717 SrcSeq.push_back(end);
1729 if (SourceLocations.size() == 0)
1732 assert(SourceLocations.size() % 2 == 0 &&
1733 "ill-formed SourceLocation sequence");
1735 auto It = SourceLocations.begin();
1736 SafeBufferOptOutRegionsTy &Regions =
1737 LoadedSafeBufferOptOutMap.findAndConsLoadedOptOutMap(*It, SourceMgr);
1743 Regions.emplace_back(Begin, End);
1744 }
while (It != SourceLocations.end());
1765 if (
auto It = CheckPoints.find(FID); It != CheckPoints.end()) {
1767 const char *
Last =
nullptr;
1769 for (
const char *P : FileCheckPoints) {
1781 return DirTracer && DirTracer->hasSeenNoTrivialPPDirective();
1785 return SeenNoTrivialPPDirective;
1788void NoTrivialPPDirectiveTracer::setSeenNoTrivialPPDirective() {
1789 if (InMainFile && !SeenNoTrivialPPDirective)
1790 SeenNoTrivialPPDirective =
true;
1796 InMainFile = (FID == PP.getSourceManager().getMainFileID());
1805 setSeenNoTrivialPPDirective();
Defines enum values for all the target-independent builtin functions.
This is the interface for scanning header and source files to get the minimum necessary preprocessor ...
Defines the clang::FileManager interface and associated types.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
Defines the clang::MacroInfo and clang::MacroDirective classes.
Defines the clang::Module class, which describes a module in the source code.
Defines the PreprocessorLexer interface.
static bool MacroDefinitionEquals(const MacroInfo *MI, ArrayRef< TokenValue > Tokens)
Compares macro tokens with a specified token value sequence.
static constexpr unsigned CheckPointStepSize
Minimum distance between two check points, in tokens.
Defines the clang::Preprocessor interface.
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
virtual ~CodeCompletionHandler()
Concrete class used by the front-end to report problems and issues.
virtual ~EmptylineHandler()
virtual ~ExternalPreprocessorSource()
virtual void updateOutOfDateIdentifier(const IdentifierInfo &II)=0
Update an out-of-date identifier.
A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...
Cached information about one file (either on disk or in the virtual file system).
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Provides lookups to, and iteration over, IdentiferInfo objects.
One of these records is kept for each identifier that is lexed.
bool IsKeywordInCPlusPlus() const
Return true if this identifier would be a keyword in C++ mode.
tok::TokenKind getTokenID() const
If this is a source-language token (e.g.
void setIsPoisoned(bool Value=true)
setIsPoisoned - Mark this identifier as poisoned.
bool isPoisoned() const
Return true if this token has been poisoned.
bool isImportKeyword() const
Determine whether this is the contextual keyword import.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
bool isOutOfDate() const
Determine whether the information for this identifier is out of date with respect to the external sou...
void setIsFutureCompatKeyword(bool Val)
StringRef getName() const
Return the actual identifier string.
bool isFutureCompatKeyword() const
is/setIsFutureCompatKeyword - Initialize information about whether or not this language token is a ke...
bool isExtensionToken() const
get/setExtension - Initialize information about whether or not this language token is an extension.
@ FEM_UnsetOnCommandLine
Used only for FE option processing; this is only used to indicate that the user did not specify an ex...
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
MacroArgs - An instance of this class captures information about the formal arguments specified to a ...
A description of the current definition of a macro.
MacroInfo * getMacroInfo() const
Get the MacroInfo that should be used for this definition.
MacroInfo * getMacroInfo()
SourceLocation getLocation() const
Encapsulates the data about a macro definition (e.g.
const_tokens_iterator tokens_begin() const
unsigned getNumTokens() const
Return the number of tokens that this macro expands to.
const Token & getReplacementToken(unsigned Tok) const
bool isBuiltinMacro() const
Return true if this macro requires processing before expansion.
bool isObjectLike() const
Abstract interface for a module loader.
static std::string getFlatNameFromPath(ModuleIdPath Path)
Represents a macro directive exported by a module.
static ModuleNameLoc * Create(Preprocessor &PP, ModuleIdPath Path)
SourceRange getRange() const
Describes a module or submodule.
@ Hidden
All of the names in this module are hidden.
llvm::SmallSetVector< Module *, 2 > Imports
The set of modules imported by this module, and on which this module depends.
void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD, SourceRange Range, const MacroArgs *Args) override
Called by Preprocessor::HandleMacroExpandedIdentifier when a macro invocation is found.
bool hasSeenNoTrivialPPDirective() const
void LexedFileChanged(FileID FID, LexedFileChangeReason Reason, SrcMgr::CharacteristicKind FileType, FileID PrevFID, SourceLocation Loc) override
Callback invoked whenever the Lexer moves to a different file for lexing.
NumericLiteralParser - This performs strict semantic analysis of the content of a ppnumber,...
PragmaNamespace - This PragmaHandler subdivides the namespace of pragmas, allowing hierarchical pragm...
A record of the steps taken while preprocessing a source file, including the various preprocessing di...
void setConditionalLevels(ArrayRef< PPConditionalInfo > CL)
PreprocessorOptions - This class is used for passing the various options used in preprocessor initial...
std::string PCHThroughHeader
If non-empty, the filename used in an include directive in the primary source file (or command-line p...
bool GeneratePreamble
True indicates that a preamble is being generated.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
bool markIncluded(FileEntryRef File)
Mark the file as included.
void FinalizeForModelFile()
Cleanup after model file parsing.
bool FinishLexStringLiteral(Token &Result, std::string &String, const char *DiagnosticTag, bool AllowMacroExpansion)
Complete the lexing of a string literal where the first token has already been lexed (see LexStringLi...
bool creatingPCHWithThroughHeader()
True if creating a PCH with a through header.
void DumpToken(const Token &Tok, bool DumpFlags=false) const
Print the token to stderr, used for debugging.
void EnterModuleSuffixTokenStream(ArrayRef< Token > Toks)
void InitializeForModelFile()
Initialize the preprocessor to parse a model file.
const MacroInfo * getMacroInfo(const IdentifierInfo *II) const
void setCodeCompletionTokenRange(const SourceLocation Start, const SourceLocation End)
Set the code completion token range for detecting replacement range later on.
bool LexAfterModuleImport(Token &Result)
Lex a token following the 'import' contextual keyword.
macro_iterator macro_begin(bool IncludeExternalMacros=true) const
void CreateString(StringRef Str, Token &Tok, SourceLocation ExpansionLocStart=SourceLocation(), SourceLocation ExpansionLocEnd=SourceLocation())
Plop the specified string into a scratch buffer and set the specified token's location and length to ...
bool isSafeBufferOptOut(const SourceManager &SourceMgr, const SourceLocation &Loc) const
const char * getCheckPoint(FileID FID, const char *Start) const
Returns a pointer into the given file's buffer that's guaranteed to be between tokens.
IdentifierInfo * LookUpIdentifierInfo(Token &Identifier) const
Given a tok::raw_identifier token, look up the identifier information for the token and install it in...
void DumpMacro(const MacroInfo &MI) const
void setCodeCompletionReached()
Note that we hit the code-completion point.
bool SetCodeCompletionPoint(FileEntryRef File, unsigned Line, unsigned Column)
Specify the point at which code-completion will be performed.
void Lex(Token &Result)
Lex the next token for this preprocessor.
const TranslationUnitKind TUKind
The kind of translation unit we are processing.
bool EnterSourceFile(FileID FID, ConstSearchDirIterator Dir, SourceLocation Loc, bool IsFirstIncludeOfFile=true)
Add a source file to the top of the include stack and start lexing tokens from it instead of the curr...
void addCommentHandler(CommentHandler *Handler)
Add the specified comment handler to the preprocessor.
void removeCommentHandler(CommentHandler *Handler)
Remove the specified comment handler.
void HandlePoisonedIdentifier(Token &Identifier)
Display reason for poisoned identifier.
bool HandleIdentifier(Token &Identifier)
Callback invoked when the lexer reads an identifier and has filled in the tokens IdentifierInfo membe...
void addPPCallbacks(std::unique_ptr< PPCallbacks > C)
bool enterOrExitSafeBufferOptOutRegion(bool isEnter, const SourceLocation &Loc)
Alter the state of whether this PP currently is in a "-Wunsafe-buffer-usage" opt-out region.
void EnterMainSourceFile()
Enter the specified FileID as the main source file, which implicitly adds the builtin defines etc.
const MacroAnnotations & getMacroAnnotations(const IdentifierInfo *II) const
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
macro_iterator macro_end(bool IncludeExternalMacros=true) const
SourceManager & getSourceManager() const
bool isBacktrackEnabled() const
True if EnableBacktrackAtThisPos() was called and caching of tokens is on.
MacroDefinition getMacroDefinition(const IdentifierInfo *II)
bool isPreprocessedModuleFile() const
Whether the main file is preprocessed module file.
void SetPoisonReason(IdentifierInfo *II, unsigned DiagID)
Specifies the reason for poisoning an identifier.
bool getCommentRetentionState() const
Module * getCurrentModuleImplementation()
Retrieves the module whose implementation we're current compiling, if any.
MacroMap::const_iterator macro_iterator
void createPreprocessingRecord()
Create a new preprocessing record, which will keep track of all macro expansions, macro definitions,...
SourceLocation SplitToken(SourceLocation TokLoc, unsigned Length)
Split the first Length characters out of the token starting at TokLoc and return a location pointing ...
Module * getCurrentModule()
Retrieves the module that we're currently building, if any.
bool isPPInSafeBufferOptOutRegion()
void makeModuleVisible(Module *M, SourceLocation Loc, bool IncludeExports=true)
bool hadModuleLoaderFatalFailure() const
void setCurrentFPEvalMethod(SourceLocation PragmaLoc, LangOptions::FPEvalMethodKind Val)
bool HandleModuleContextualKeyword(Token &Result)
Callback invoked when the lexer sees one of export, import or module token at the start of a line.
const TargetInfo & getTargetInfo() const
bool LexHeaderName(Token &Result, bool AllowMacroExpansion=true)
Lex a token, forming a header-name token if possible.
bool isPCHThroughHeader(const FileEntry *FE)
Returns true if the FileEntry is the PCH through header.
void DumpLocation(SourceLocation Loc) const
bool parseSimpleIntegerLiteral(Token &Tok, uint64_t &Value)
Parses a simple integer literal to get its numeric value.
void LexUnexpandedToken(Token &Result)
Just like Lex, but disables macro expansion of identifier tokens.
bool creatingPCHWithPragmaHdrStop()
True if creating a PCH with a pragma hdrstop.
void Initialize(const TargetInfo &Target, const TargetInfo *AuxTarget=nullptr)
Initialize the preprocessor using information about the target.
FileID getPredefinesFileID() const
Returns the FileID for the preprocessor predefines.
llvm::BumpPtrAllocator & getPreprocessorAllocator()
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 ...
bool HandleComment(Token &result, SourceRange Comment)
HeaderSearch & getHeaderSearchInfo() const
bool setDeserializedSafeBufferOptOutMap(const SmallVectorImpl< SourceLocation > &SrcLocSeqs)
ExternalPreprocessorSource * getExternalSource() const
void HandleDirective(Token &Result)
Callback invoked when the lexer sees a # token at the start of a line.
SmallVector< SourceLocation, 64 > serializeSafeBufferOptOutMap() const
void recomputeCurLexerKind()
Recompute the current lexer kind based on the CurLexer/ CurTokenLexer pointers.
OptionalFileEntryRef LookupFile(SourceLocation FilenameLoc, StringRef Filename, bool isAngled, ConstSearchDirIterator FromDir, const FileEntry *FromFile, ConstSearchDirIterator *CurDir, SmallVectorImpl< char > *SearchPath, SmallVectorImpl< char > *RelativePath, ModuleMap::KnownHeader *SuggestedModule, bool *IsMapped, bool *IsFrameworkFound, bool SkipCache=false, bool OpenFile=true, bool CacheFailures=true)
Given a "foo" or <foo> reference, look up the indicated file.
IdentifierTable & getIdentifierTable()
const LangOptions & getLangOpts() const
void setTUFPEvalMethod(LangOptions::FPEvalMethodKind Val)
void CodeCompleteIncludedFile(llvm::StringRef Dir, bool IsAngled)
Hook used by the lexer to invoke the "included file" code completion point.
llvm::DenseMap< FileID, SafeBufferOptOutRegionsTy > LoadedRegions
void PoisonSEHIdentifiers(bool Poison=true)
size_t getTotalMemory() const
void LexTokensUntilEOF(std::vector< Token > *Tokens=nullptr)
Lex all tokens for this preprocessor until (and excluding) end of file.
bool isNextPPTokenOneOf(Ts... Ks) const
isNextPPTokenOneOf - Check whether the next pp-token is one of the specificed token kind.
bool usingPCHWithPragmaHdrStop()
True if using a PCH with a pragma hdrstop.
void CodeCompleteNaturalLanguage()
Hook used by the lexer to invoke the "natural language" code completion point.
void EndSourceFile()
Inform the preprocessor callbacks that processing is complete.
bool LexModuleNameContinue(Token &Tok, SourceLocation UseLoc, SmallVectorImpl< Token > &Suffix, SmallVectorImpl< IdentifierLoc > &Path, bool AllowMacroExpansion=true, bool IsPartition=false)
void CollectPPImportSuffix(SmallVectorImpl< Token > &Toks, bool StopUntilEOD=false)
Collect the tokens of a C++20 pp-import-suffix.
DiagnosticsEngine & getDiagnostics() const
bool hasSeenNoTrivialPPDirective() const
Whether we've seen pp-directives which may have changed the preprocessing state.
StringRef getLastMacroWithSpelling(SourceLocation Loc, ArrayRef< TokenValue > Tokens) const
Return the name of the macro defined before Loc that has spelling Tokens.
void setCodeCompletionIdentifierInfo(IdentifierInfo *Filter)
Set the code completion token for filtering purposes.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const
Forwarding function for diagnostics.
void SkipTokensWhileUsingPCH()
Skip tokens until after the include of the through header or until after a pragma hdrstop.
bool usingPCHWithThroughHeader()
True if using a PCH with a through header.
bool CollectPPImportSuffixAndEnterStream(SmallVectorImpl< Token > &Toks, bool StopUntilEOD=false)
Preprocessor(const PreprocessorOptions &PPOpts, DiagnosticsEngine &diags, const LangOptions &LangOpts, SourceManager &SM, HeaderSearch &Headers, ModuleLoader &TheModuleLoader, IdentifierInfoLookup *IILookup=nullptr, bool OwnsHeaderSearch=false, TranslationUnitKind TUKind=TU_Complete)
ScratchBuffer - This class exposes a simple interface for the dynamic construction of tokens.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
void print(raw_ostream &OS, const SourceManager &SM) const
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
This class handles loading and caching of source files into memory.
std::optional< StringRef > getBufferDataOrNone(FileID FID) const
Return a StringRef to the source buffer data for the specified FileID, returning std::nullopt if inva...
A trivial tuple used to represent a source range.
StringLiteralParser - This decodes string escape characters and performs wide string analysis and Tra...
Exposes information about the current target.
Token - This structure provides full information about a lexed token.
IdentifierInfo * getIdentifierInfo() const
bool hasUCN() const
Returns true if this token contains a universal character name.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
unsigned getLength() const
bool isExpandDisabled() const
Return true if this identifier token should never be expanded in the future, due to C99 6....
void setKind(tok::TokenKind K)
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)) {....
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
bool isOneOf(Ts... Ks) const
@ HasSeenNoTrivialPPDirective
bool isModuleContextualKeyword(bool AllowExport=true) const
Return true if we have a C++20 modules contextual keyword(export, importor module).
bool hasLeadingSpace() const
Return true if this token has whitespace before it.
bool hasLeadingEmptyMacro() const
Return true if this token has an empty macro before it.
bool isNot(tok::TokenKind K) const
void startToken()
Reset all flags to cleared.
bool needsCleaning() const
Return true if this token has trigraphs or escaped newlines in it.
void setIdentifierInfo(IdentifierInfo *II)
void setFlagValue(TokenFlags Flag, bool Val)
Set a flag to either true or false.
StringRef getRawIdentifier() const
getRawIdentifier - For a raw identifier token (i.e., an identifier lexed in raw mode),...
void setFlag(TokenFlags Flag)
Set the specified flag.
Defines the clang::TargetInfo interface.
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
const char * getTokenName(TokenKind Kind) LLVM_READNONE
Determines the name of a token as used within the front end.
const char * getKeywordSpelling(TokenKind Kind) LLVM_READNONE
Determines the spelling of simple keyword and contextual keyword tokens like 'int' and 'dynamic_cast'...
The JSON file list parser is used to communicate input to InstallAPI.
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
llvm::Registry< PragmaHandler > PragmaHandlerRegistry
Registry of pragma handlers added by plugins.
void expandUCNs(SmallVectorImpl< char > &Buf, StringRef Input)
Copy characters from Input to Buf, expanding any UCNs.
ArrayRef< IdentifierLoc > ModuleIdPath
A sequence of identifier/location pairs used to describe a particular module or submodule,...
std::pair< FileID, unsigned > FileIDAndOffset
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
bool isPreprocessedModuleFile(StringRef Source)
Scan an input source buffer, and check whether the input source is a preprocessed output.
@ Result
The result type of a method or function.
TranslationUnitKind
Describes the kind of translation unit being processed.
@ TU_Prefix
The translation unit is a prefix to a translation unit, and is not complete.