56#include "llvm/ADT/APInt.h"
57#include "llvm/ADT/ArrayRef.h"
58#include "llvm/ADT/DenseMap.h"
59#include "llvm/ADT/STLExtras.h"
60#include "llvm/ADT/ScopeExit.h"
61#include "llvm/ADT/SmallVector.h"
62#include "llvm/ADT/StringRef.h"
63#include "llvm/Support/Capacity.h"
64#include "llvm/Support/ErrorHandling.h"
65#include "llvm/Support/FormatVariadic.h"
66#include "llvm/Support/MemoryBuffer.h"
67#include "llvm/Support/MemoryBufferRef.h"
68#include "llvm/Support/SaveAndRestore.h"
69#include "llvm/Support/raw_ostream.h"
93 : PPOpts(PPOpts), Diags(&diags), LangOpts(opts),
94 FileMgr(Headers.getFileMgr()), SourceMgr(SM),
95 ScratchBuf(new
ScratchBuffer(SourceMgr)), HeaderInfo(Headers),
96 TheModuleLoader(TheModuleLoader), ExternalSource(
nullptr),
100 Identifiers(IILookup), PragmaHandlers(new
PragmaNamespace(StringRef())),
102 CurSubmoduleState(&NullSubmoduleState) {
103 OwnsHeaderSearch = OwnsHeaders;
109 KeepComments =
false;
110 KeepMacroComments =
false;
111 SuppressIncludeNotFoundError =
false;
114 DisableMacroExpansion =
false;
115 MacroExpansionInDirectivesOverride =
false;
118 InMacroArgPreExpansion =
false;
119 NumCachedTokenLexers = 0;
120 PragmasEnabled =
true;
121 ParsingIfOrElifDirective =
false;
122 PreprocessedOutput =
false;
125 ReadMacrosFromExternalSource =
false;
127 LastExportKeyword.startToken();
129 BuiltinInfo = std::make_unique<Builtin::Context>();
139 RegisterBuiltinPragmas();
142 RegisterBuiltinMacros();
144 if(LangOpts.Borland) {
155 Ident__exception_info = Ident__exception_code =
nullptr;
156 Ident__abnormal_termination = Ident___exception_info =
nullptr;
157 Ident___exception_code = Ident___abnormal_termination =
nullptr;
158 Ident_GetExceptionInfo = Ident_GetExceptionCode =
nullptr;
159 Ident_AbnormalTermination =
nullptr;
166 IncrementalProcessing = LangOpts.IncrementalExtensions;
170 SkippingUntilPragmaHdrStop =
true;
174 !this->PPOpts.ImplicitPCHInclude.empty())
175 SkippingUntilPCHThroughHeader =
true;
178 PreambleConditionalStack.startRecording();
180 MaxTokens = LangOpts.MaxTokens;
186 IncludeMacroStack.clear();
191 std::fill(TokenLexerCache, TokenLexerCache + NumCachedTokenLexers,
nullptr);
192 CurTokenLexer.reset();
195 for (
MacroArgs *ArgList = MacroArgCache; ArgList;)
196 ArgList = ArgList->deallocate();
199 if (OwnsHeaderSearch)
205 assert((!this->Target || this->Target == &Target) &&
206 "Invalid override of target information");
207 this->Target = &Target;
209 assert((!this->AuxTarget || this->AuxTarget == AuxTarget) &&
210 "Invalid override of aux target information.");
211 this->AuxTarget = AuxTarget;
214 BuiltinInfo->InitializeTarget(Target, AuxTarget);
215 HeaderInfo.setTarget(Target);
218 Identifiers.AddKeywords(LangOpts);
232 NumEnteredSourceFiles = 0;
235 PragmaHandlersBackup = std::move(PragmaHandlers);
236 PragmaHandlers = std::make_unique<PragmaNamespace>(StringRef());
237 RegisterBuiltinPragmas();
240 PredefinesFileID =
FileID();
244 NumEnteredSourceFiles = 1;
246 PragmaHandlers = std::move(PragmaHandlersBackup);
250 std::string TokenStr;
251 llvm::raw_string_ostream OS(TokenStr);
258 if (!
Tok.isAnnotation()) {
267 llvm::errs() << llvm::formatv(
"{0,-48} ", OS.str());
269 if (!DumpFlags)
return;
271 auto Loc =
Tok.getLocation();
272 llvm::errs() <<
"Loc=<";
285 if (Loc.isFileID()) {
289 int LineWidth = llvm::utostr(PLoc.
getLine()).size();
294 const int ReservedSpace = 6;
296 int LeftSpace = ReservedSpace - LineWidth -
ColumnWidth;
297 int Padding = std::max<int>(0, LeftSpace);
299 llvm::errs().indent(Padding);
303 if (
Tok.isAtStartOfLine())
304 llvm::errs() <<
" [StartOfLine]";
305 if (
Tok.hasLeadingSpace())
306 llvm::errs() <<
" [LeadingSpace]";
307 if (
Tok.isExpandDisabled())
308 llvm::errs() <<
" [ExpandDisabled]";
309 if (
Tok.needsCleaning()) {
310 const char *Start = SourceMgr.getCharacterData(
Tok.getLocation());
311 llvm::errs() <<
" [UnClean='" << StringRef(Start,
Tok.getLength()) <<
"']";
316 Loc.
print(llvm::errs(), SourceMgr);
320 llvm::errs() <<
"MACRO: ";
321 for (
unsigned i = 0, e = MI.
getNumTokens(); i != e; ++i) {
325 llvm::errs() <<
"\n";
329 llvm::errs() <<
"\n*** Preprocessor Stats:\n";
330 llvm::errs() << NumDirectives <<
" directives found:\n";
331 llvm::errs() <<
" " << NumDefined <<
" #define.\n";
332 llvm::errs() <<
" " << NumUndefined <<
" #undef.\n";
333 llvm::errs() <<
" #include/#include_next/#import:\n";
334 llvm::errs() <<
" " << NumEnteredSourceFiles <<
" source files entered.\n";
335 llvm::errs() <<
" " << MaxIncludeStackDepth <<
" max include stack depth\n";
336 llvm::errs() <<
" " << NumIf <<
" #if/#ifndef/#ifdef.\n";
337 llvm::errs() <<
" " << NumElse <<
" #else/#elif/#elifdef/#elifndef.\n";
338 llvm::errs() <<
" " << NumEndif <<
" #endif.\n";
339 llvm::errs() <<
" " << NumPragma <<
" #pragma.\n";
340 llvm::errs() << NumSkipped <<
" #if/#ifndef#ifdef regions skipped\n";
342 llvm::errs() << NumMacroExpanded <<
"/" << NumFnMacroExpanded <<
"/"
343 << NumBuiltinMacroExpanded <<
" obj/fn/builtin macros expanded, "
344 << NumFastMacroExpanded <<
" on the fast path.\n";
345 llvm::errs() << (NumFastTokenPaste+NumTokenPaste)
346 <<
" token paste (##) operations performed, "
347 << NumFastTokenPaste <<
" on the fast path.\n";
349 llvm::errs() <<
"\nPreprocessor Memory: " <<
getTotalMemory() <<
"B total";
351 llvm::errs() <<
"\n BumpPtr: " << BP.getTotalMemory();
352 llvm::errs() <<
"\n Macro Expanded Tokens: "
353 << llvm::capacity_in_bytes(MacroExpandedTokens);
354 llvm::errs() <<
"\n Predefines Buffer: " << Predefines.capacity();
356 llvm::errs() <<
"\n Macros: "
357 << llvm::capacity_in_bytes(CurSubmoduleState->Macros);
358 llvm::errs() <<
"\n #pragma push_macro Info: "
359 << llvm::capacity_in_bytes(PragmaPushMacroInfo);
360 llvm::errs() <<
"\n Poison Reasons: "
361 << llvm::capacity_in_bytes(PoisonReasons);
362 llvm::errs() <<
"\n Comment Handlers: "
363 << llvm::capacity_in_bytes(CommentHandlers) <<
"\n";
366llvm::iterator_range<Preprocessor::macro_iterator>
368 if (IncludeExternalMacros && ExternalSource &&
369 !ReadMacrosFromExternalSource) {
370 ReadMacrosFromExternalSource =
true;
371 ExternalSource->ReadDefinedMacros();
375 CurSubmoduleState->Macros.try_emplace(
Macro.II);
377 return CurSubmoduleState->Macros;
381 return BP.getTotalMemory()
382 + llvm::capacity_in_bytes(MacroExpandedTokens)
383 + Predefines.capacity()
386 + llvm::capacity_in_bytes(CurSubmoduleState->Macros)
387 + llvm::capacity_in_bytes(PragmaPushMacroInfo)
388 + llvm::capacity_in_bytes(PoisonReasons)
389 + llvm::capacity_in_bytes(CommentHandlers);
396 std::equal(Tokens.begin(), Tokens.end(), MI->
tokens_begin());
403 StringRef BestSpelling;
404 for (
const auto &M :
macros()) {
406 M.second.findDirectiveAtLoc(Loc, SourceMgr);
416 (Location.isValid() &&
417 SourceMgr.isBeforeInTranslationUnit(BestLocation, Location))) {
418 BestLocation = Location;
419 BestSpelling = M.first->getName();
426 if (InCachingLexMode())
427 CurLexerCallback = CLK_CachingLexer;
429 CurLexerCallback = CurLexer->isDependencyDirectivesLexer()
430 ? CLK_DependencyDirectivesLexer
432 else if (CurTokenLexer)
433 CurLexerCallback = CLK_TokenLexer;
435 CurLexerCallback = CLK_Lexer;
439 unsigned CompleteLine,
440 unsigned CompleteColumn) {
441 assert(CompleteLine && CompleteColumn &&
"Starts from 1:1");
442 assert(!CodeCompletionFile &&
"Already set");
445 std::optional<llvm::MemoryBufferRef> Buffer =
446 SourceMgr.getMemoryBufferForFileOrNone(
File);
451 const char *Position = Buffer->getBufferStart();
453 for (; *Position; ++Position) {
454 if (*Position !=
'\r' && *Position !=
'\n')
458 if ((Position[1] ==
'\r' || Position[1] ==
'\n') &&
459 Position[0] != Position[1])
466 Position += CompleteColumn - 1;
470 if (SkipMainFilePreamble.first &&
471 SourceMgr.getFileEntryForID(SourceMgr.getMainFileID()) ==
File) {
472 if (Position - Buffer->getBufferStart() < SkipMainFilePreamble.first)
473 Position = Buffer->getBufferStart() + SkipMainFilePreamble.first;
476 if (Position > Buffer->getBufferEnd())
477 Position = Buffer->getBufferEnd();
479 CodeCompletionFile =
File;
480 CodeCompletionOffset = Position - Buffer->getBufferStart();
482 auto NewBuffer = llvm::WritableMemoryBuffer::getNewUninitMemBuffer(
483 Buffer->getBufferSize() + 1, Buffer->getBufferIdentifier());
484 char *NewBuf = NewBuffer->getBufferStart();
485 char *NewPos = std::copy(Buffer->getBufferStart(), Position, NewBuf);
487 std::copy(Position, Buffer->getBufferEnd(), NewPos+1);
488 SourceMgr.overrideFileContents(
File, std::move(NewBuffer));
497 CodeComplete->CodeCompleteIncludedFile(Dir, IsAngled);
503 CodeComplete->CodeCompleteNaturalLanguage();
513 if (
Tok.isNot(tok::raw_identifier) && !
Tok.hasUCN()) {
516 return II->getName();
520 if (
Tok.needsCleaning())
521 Buffer.resize(
Tok.getLength());
523 const char *Ptr = Buffer.data();
525 return StringRef(Ptr, Len);
534 Tok.setLength(Str.size());
537 SourceLocation Loc = ScratchBuf->getToken(Str.data(), Str.size(), DestPtr);
539 if (ExpansionLocStart.
isValid())
540 Loc = SourceMgr.createExpansionLoc(Loc, ExpansionLocStart,
541 ExpansionLocEnd, Str.size());
542 Tok.setLocation(Loc);
545 if (
Tok.is(tok::raw_identifier))
546 Tok.setRawIdentifierData(DestPtr);
547 else if (
Tok.isLiteral())
548 Tok.setLiteralData(DestPtr);
556 StringRef Buffer = SM.getBufferData(LocInfo.first, &
Invalid);
563 ScratchBuf->getToken(Buffer.data() + LocInfo.second, Length, DestPtr);
575 if (!
getLangOpts().isCompilingModuleImplementation())
591 assert(NumEnteredSourceFiles == 0 &&
"Cannot reenter the main file!");
592 FileID MainFileID = SourceMgr.getMainFileID();
601 if (!SourceMgr.isLoadedFileID(MainFileID)) {
607 if (SkipMainFilePreamble.first > 0)
608 CurLexer->SetByteOffset(SkipMainFilePreamble.first,
609 SkipMainFilePreamble.second);
626 std::optional<StringRef> Input =
629 MainFileIsPreprocessedModuleFile =
631 if (Input && !MainFileIsPreprocessedModuleFile && hasDeferredGMFInputs())
633 auto Tracer = std::make_unique<NoTrivialPPDirectiveTracer>(*
this);
634 DirTracer = Tracer.get();
636 std::optional<Token> FirstPPTok = CurLexer->peekNextPPToken();
638 FirstPPTokenLoc = FirstPPTok->getLocation();
647 if (hasDeferredGMFInputs()) {
648 if (PredefinesWereReplaced) {
653 DeferredGMFInputs = std::move(Predefines);
659 Predefines += DeferredGMFInputs;
661 if (MainFileModuleUnitKind ==
663 Predefines +=
"# 1 \"<implicit-global-module-fragment>\" 1\nmodule;\n";
664 HasSynthesizedGMF =
true;
666 DeferredGMFInputs.clear();
671 std::unique_ptr<llvm::MemoryBuffer> SB =
672 llvm::MemoryBuffer::getMemBufferCopy(Predefines,
"<built-in>");
673 assert(SB &&
"Cannot create predefined source buffer");
674 FileID FID = SourceMgr.createFileID(std::move(SB));
675 assert(FID.
isValid() &&
"Could not create FileID for predefines?");
676 setPredefinesFileID(FID);
681 if (!PPOpts.PCHThroughHeader.empty()) {
686 false,
nullptr,
nullptr,
687 nullptr,
nullptr,
nullptr,
692 << PPOpts.PCHThroughHeader;
695 setPCHThroughHeaderFileID(
705void Preprocessor::EnterDeferredGMFInputs(
SourceLocation IncludeLoc) {
706 if (!hasDeferredGMFInputs())
711 std::unique_ptr<llvm::MemoryBuffer> MB = llvm::MemoryBuffer::getMemBufferCopy(
712 DeferredGMFInputs,
"<gmf-command-line-inputs>");
713 DeferredGMFInputs.clear();
714 DeferredGMFInputsFileID =
715 SourceMgr.createFileID(std::move(MB),
SrcMgr::C_User, 0, 0, IncludeLoc);
719void Preprocessor::setPCHThroughHeaderFileID(
FileID FID) {
720 assert(PCHThroughHeaderFileID.
isInvalid() &&
721 "PCHThroughHeaderFileID already set!");
722 PCHThroughHeaderFileID = FID;
726 assert(PCHThroughHeaderFileID.isValid() &&
727 "Invalid PCH through header FileID");
728 return FE == SourceMgr.getFileEntryForID(PCHThroughHeaderFileID);
733 PCHThroughHeaderFileID.isValid();
738 PCHThroughHeaderFileID.isValid();
755 bool ReachedMainFileEOF =
false;
756 bool UsingPCHThroughHeader = SkippingUntilPCHThroughHeader;
757 bool UsingPragmaHdrStop = SkippingUntilPragmaHdrStop;
762 CurLexerCallback(*
this,
Tok);
763 if (
Tok.is(tok::eof) && !InPredefines) {
764 ReachedMainFileEOF =
true;
767 if (UsingPCHThroughHeader && !SkippingUntilPCHThroughHeader)
769 if (UsingPragmaHdrStop && !SkippingUntilPragmaHdrStop)
772 if (ReachedMainFileEOF) {
773 if (UsingPCHThroughHeader)
775 << PPOpts.PCHThroughHeader << 1;
776 else if (!PPOpts.PCHWithHdrStopCreate)
781void Preprocessor::replayPreambleConditionalStack() {
783 if (PreambleConditionalStack.isReplaying()) {
785 "CurPPLexer is null when calling replayPreambleConditionalStack.");
787 PreambleConditionalStack.doneReplaying();
788 if (PreambleConditionalStack.reachedEOFWhileSkipping())
789 SkipExcludedConditionalBlock(
790 PreambleConditionalStack.SkipInfo->HashTokenLoc,
791 PreambleConditionalStack.SkipInfo->IfTokenLoc,
792 PreambleConditionalStack.SkipInfo->FoundNonSkipPortion,
793 PreambleConditionalStack.SkipInfo->FoundElse,
794 PreambleConditionalStack.SkipInfo->ElseLoc);
801 Callbacks->EndOfMainFile();
812 assert(!Identifier.
getRawIdentifier().empty() &&
"No raw identifier data!");
822 StringRef CleanedStr =
getSpelling(Identifier, IdentifierBuffer);
824 if (Identifier.
hasUCN()) {
847 PoisonReasons[II] = DiagID;
851 assert(Ident__exception_code && Ident__exception_info);
852 assert(Ident___exception_code && Ident___exception_info);
853 Ident__exception_code->setIsPoisoned(Poison);
854 Ident___exception_code->setIsPoisoned(Poison);
855 Ident_GetExceptionCode->setIsPoisoned(Poison);
856 Ident__exception_info->setIsPoisoned(Poison);
857 Ident___exception_info->setIsPoisoned(Poison);
858 Ident_GetExceptionInfo->setIsPoisoned(Poison);
859 Ident__abnormal_termination->setIsPoisoned(Poison);
860 Ident___abnormal_termination->setIsPoisoned(Poison);
861 Ident_AbnormalTermination->setIsPoisoned(Poison);
866 "Can't handle identifiers without identifier info!");
867 llvm::DenseMap<IdentifierInfo*,unsigned>::const_iterator it =
869 if(it == PoisonReasons.end())
870 Diag(Identifier, diag::err_pp_used_poisoned_id);
875void Preprocessor::updateOutOfDateIdentifier(
const IdentifierInfo &II)
const {
878 "getExternalSource() should not return nullptr");
892 "Can't handle identifiers without identifier info!");
902 bool CurrentIsPoisoned =
false;
903 const bool IsSpecialVariadicMacro =
904 &II == Ident__VA_ARGS__ || &II == Ident__VA_OPT__;
905 if (IsSpecialVariadicMacro)
908 updateOutOfDateIdentifier(II);
911 if (IsSpecialVariadicMacro)
923 const auto *MI = MD.getMacroInfo();
924 assert(MI &&
"macro definition with no macro info?");
925 if (!DisableMacroExpansion) {
930 return HandleMacroExpandedIdentifier(Identifier, MD);
937 Diag(Identifier, diag::pp_disabled_macro_expansion);
957 Diag(Identifier, diag::warn_pp_identifier_is_cpp_keyword) << &II;
964 Diag(Identifier, diag::ext_token_used);
968 !CurLexer->isLexingRawMode() && !CurLexer->isPragmaLexer() &&
969 !CurLexer->ParsingPreprocessorDirective &&
984 while (!CurLexerCallback(*
this,
Result))
987 if (
Result.is(tok::unknown) && TheModuleLoader.HadFatalFailure)
990 if (
Result.is(tok::code_completion) &&
Result.getIdentifierInfo()) {
996 Result.setIdentifierInfo(
nullptr);
1004 if (
getLangOpts().CPlusPlusModules && LexLevel == 1 &&
1006 switch (
Result.getKind()) {
1007 case tok::l_paren:
case tok::l_square:
case tok::l_brace:
1008 StdCXXImportSeqState.handleOpenBracket();
1010 case tok::r_paren:
case tok::r_square:
1011 StdCXXImportSeqState.handleCloseBracket();
1014 StdCXXImportSeqState.handleCloseBrace();
1016#define PRAGMA_ANNOTATION(X) case tok::annot_##X:
1018#include "clang/Basic/TokenKinds.def"
1019#undef PRAGMA_ANNOTATION
1022 case tok::annot_module_include:
1024 TrackGMFState.handleSemi();
1025 StdCXXImportSeqState.handleSemi();
1026 ModuleDeclState.handleSemi();
1030 TrackGMFState.handleSemi();
1031 StdCXXImportSeqState.handleSemi();
1032 ModuleDeclState.handleSemi();
1034 TrackGMFState.handleMisc();
1035 StdCXXImportSeqState.handleMisc();
1036 ModuleDeclState.handleMisc();
1039 case tok::header_name:
1040 case tok::annot_header_unit:
1041 StdCXXImportSeqState.handleHeaderName();
1043 case tok::kw_export:
1046 TrackGMFState.handleExport();
1047 StdCXXImportSeqState.handleExport();
1048 ModuleDeclState.handleExport();
1051 ModuleDeclState.handleColon();
1053 case tok::kw_import:
1054 if (StdCXXImportSeqState.atTopLevel()) {
1055 TrackGMFState.handleImport(StdCXXImportSeqState.afterTopLevelSeq());
1056 StdCXXImportSeqState.handleImport();
1059 case tok::kw_module:
1060 if (StdCXXImportSeqState.atTopLevel()) {
1063 TrackGMFState.handleModule(StdCXXImportSeqState.afterTopLevelSeq());
1064 ModuleDeclState.handleModule();
1067 case tok::annot_module_name:
1068 ModuleDeclState.handleModuleName(
1070 if (ModuleDeclState.isModuleCandidate())
1074 TrackGMFState.handleMisc();
1075 StdCXXImportSeqState.handleMisc();
1076 ModuleDeclState.handleMisc();
1081 if (RecordCheckPoints && CurLexer &&
1083 CheckPoints[CurLexer->getFileID()].push_back(CurLexer->BufferPtr);
1084 CheckPointCounter = 0;
1087 if (
Result.isNot(tok::kw_export))
1088 LastExportKeyword.startToken();
1095 if (LexLevel == 0 && !PendingDestroyLexers.empty())
1096 PendingDestroyLexers.clear();
1098 if ((LexLevel == 0 || PreprocessToken) &&
1111 if (
Tok.isOneOf(tok::unknown, tok::eof, tok::eod))
1113 if (Tokens !=
nullptr)
1114 Tokens->push_back(
Tok);
1135 if (CurPPLexer->ParsingFilename)
1138 CurPPLexer->LexIncludeFilename(FilenameTok);
1146 if (FilenameTok.
is(tok::less) && AllowMacroExpansion) {
1153 FilenameBuffer.push_back(
'<');
1159 while (FilenameTok.
isNot(tok::greater)) {
1161 if (FilenameTok.
isOneOf(tok::eod, tok::eof)) {
1163 Diag(Start, diag::note_matching) << tok::less;
1170 if (FilenameTok.
is(tok::code_completion)) {
1179 FilenameBuffer.push_back(
' ');
1183 size_t PreAppendSize = FilenameBuffer.size();
1184 FilenameBuffer.resize(PreAppendSize + FilenameTok.
getLength());
1186 const char *BufPtr = &FilenameBuffer[PreAppendSize];
1187 unsigned ActualLen =
getSpelling(FilenameTok, BufPtr);
1190 if (BufPtr != &FilenameBuffer[PreAppendSize])
1191 memcpy(&FilenameBuffer[PreAppendSize], BufPtr, ActualLen);
1194 if (FilenameTok.
getLength() != ActualLen)
1195 FilenameBuffer.resize(PreAppendSize + ActualLen);
1199 FilenameTok.
setKind(tok::header_name);
1204 }
else if (FilenameTok.
is(tok::string_literal) && AllowMacroExpansion) {
1215 StringRef Str =
getSpelling(FilenameTok, FilenameBuffer);
1216 if (Str.size() >= 2 && Str.front() ==
'"' && Str.back() ==
'"')
1217 FilenameTok.
setKind(tok::header_name);
1223std::optional<Token> Preprocessor::peekNextPPToken()
const {
1225 std::optional<Token> Val;
1227 Val = CurLexer->peekNextPPToken();
1229 Val = CurTokenLexer->peekNextPPToken();
1236 return std::nullopt;
1237 for (
const IncludeStackInfo &Entry : llvm::reverse(IncludeMacroStack)) {
1239 Val = Entry.TheLexer->peekNextPPToken();
1241 Val = Entry.TheTokenLexer->peekNextPPToken();
1247 if (Entry.ThePPLexer)
1248 return std::nullopt;
1266 for (
auto &Piece : Path) {
1267 assert(Piece.getIdentifierInfo() && Piece.getLoc().isValid());
1270 Name += Piece.getIdentifierInfo()->getName();
1276 assert(!Path.empty() &&
"expect at least one identifier in a module name");
1278 totalSizeToAlloc<IdentifierLoc>(Path.size()),
alignof(ModuleNameLoc));
1279 return new (Mem) ModuleNameLoc(Path);
1285 bool AllowMacroExpansion,
1287 auto ConsumeToken = [&]() {
1288 if (AllowMacroExpansion)
1292 Suffix.push_back(
Tok);
1296 if (
Tok.isNot(tok::identifier)) {
1297 if (
Tok.is(tok::code_completion)) {
1298 CurLexer->cutOffLexing();
1299 CodeComplete->CodeCompleteModuleImport(UseLoc, Path);
1303 Diag(
Tok, diag::err_pp_module_expected_ident) << Path.empty();
1312 !AllowMacroExpansion) {
1313 Diag(
Tok, diag::err_pp_module_name_is_macro)
1314 << IsPartition <<
Tok.getIdentifierInfo();
1315 Diag(MI->getDefinitionLoc(), diag::note_macro_here)
1316 <<
Tok.getIdentifierInfo();
1320 Path.emplace_back(
Tok.getLocation(),
Tok.getIdentifierInfo());
1323 if (
Tok.isNot(tok::period))
1334 bool AllowMacroExpansion,
1336 bool LeadingSpace =
Tok.hasLeadingSpace();
1337 unsigned NumToksInDirective = DirToks.size();
1340 if (
Tok.isNot(tok::eod))
1349 DirToks.resize(NumToksInDirective);
1351 DirToks.emplace_back();
1352 DirToks.back().setKind(tok::annot_module_name);
1353 DirToks.back().setAnnotationRange(NameLoc->
getRange());
1354 DirToks.back().setAnnotationValue(
static_cast<void *
>(NameLoc));
1356 DirToks.push_back(
Tok);
1389 if (
Result.is(tok::kw_export)) {
1390 LastExportKeyword =
Result;
1403 if (LastExportKeyword.is(tok::kw_export)) {
1406 if (!LastExportKeyword.isAtPhysicalStartOfLine())
1411 if (
Result.isAtPhysicalStartOfLine())
1413 }
else if (!
Result.isAtPhysicalStartOfLine())
1416 assert(CurPPLexer &&
"CurPPLexer must not be null");
1419 CurPPLexer->ParsingPreprocessorDirective,
true);
1422 if (
auto NextTok = peekNextPPToken()) {
1423 if (NextTok->is(tok::raw_identifier))
1425 if (NextTok->isOneOf(tok::identifier, tok::colon, tok::semi)) {
1426 Result.setKind(tok::kw_module);
1427 ModuleDeclLoc =
Result.getLocation();
1437 if (
auto NextTok = peekNextPPToken()) {
1438 if (NextTok->is(tok::raw_identifier))
1440 if (NextTok->isOneOf(tok::header_name, tok::identifier, tok::colon,
1441 tok::less, tok::code_completion)) {
1442 Result.setKind(tok::kw_import);
1443 ModuleImportLoc =
Result.getLocation();
1463 bool StopUntilEOD) {
1465 Toks.emplace_back();
1468 switch (Toks.back().getKind()) {
1487 auto ToksCopy = std::make_unique<Token[]>(Toks.size());
1488 std::copy(Toks.begin(), Toks.end(), ToksCopy.get());
1489 EnterTokenStream(std::move(ToksCopy), Toks.size(),
1491 assert(CurTokenLexer &&
"Must have a TokenLexer");
1492 CurTokenLexer->setLexingCXXModuleDirective();
1496 bool IncludeExports) {
1497 CurSubmoduleState->VisibleModules.setVisible(
1498 M, Loc, IncludeExports, [](
Module *) {},
1502 Diag(ModuleImportLoc, diag::warn_module_conflict)
1503 << Path[0]->getFullModuleName()
1504 << Conflict->getFullModuleName()
1509 if (!BuildingSubmoduleStack.empty() && M != BuildingSubmoduleStack.back().M)
1510 BuildingSubmoduleStack.back().M->Imports.push_back(M);
1514 const char *DiagnosticTag,
1515 bool AllowMacroExpansion) {
1517 if (
Result.isNot(tok::string_literal)) {
1518 Diag(
Result, diag::err_expected_string_literal)
1519 << 0 << DiagnosticTag;
1526 StrToks.push_back(
Result);
1528 if (
Result.hasUDSuffix())
1531 if (AllowMacroExpansion)
1535 }
while (
Result.is(tok::string_literal));
1539 assert(Literal.isOrdinary() &&
"Didn't allow wide strings in");
1541 if (Literal.hadError)
1544 if (Literal.Pascal) {
1545 Diag(StrToks[0].getLocation(), diag::err_expected_string_literal)
1546 << 0 << DiagnosticTag;
1550 String = std::string(Literal.GetString());
1555 assert(
Tok.is(tok::numeric_constant));
1557 bool NumberInvalid =
false;
1558 StringRef Spelling =
getSpelling(
Tok, IntegerBuffer, &NumberInvalid);
1564 if (Literal.hadError || !Literal.isIntegerLiteral() || Literal.hasUDSuffix())
1566 llvm::APInt APVal(64, 0);
1567 if (Literal.GetIntegerValue(APVal))
1570 Value = APVal.getLimitedValue();
1575 assert(Handler &&
"NULL comment handler");
1576 assert(!llvm::is_contained(CommentHandlers, Handler) &&
1577 "Comment handler already registered");
1578 CommentHandlers.push_back(Handler);
1582 std::vector<CommentHandler *>::iterator Pos =
1583 llvm::find(CommentHandlers, Handler);
1584 assert(Pos != CommentHandlers.end() &&
"Comment handler not registered");
1585 CommentHandlers.erase(Pos);
1589 bool AnyPendingTokens =
false;
1591 if (H->HandleComment(*
this, Comment))
1592 AnyPendingTokens =
true;
1600void Preprocessor::emitMacroDeprecationWarning(
const Token &Identifier)
const {
1601 const MacroAnnotations &A =
1603 assert(A.DeprecationInfo &&
1604 "Macro deprecation warning without recorded annotation!");
1605 const MacroAnnotationInfo &Info = *A.DeprecationInfo;
1606 if (Info.Message.empty())
1607 Diag(Identifier, diag::warn_pragma_deprecated_macro_use)
1610 Diag(Identifier, diag::warn_pragma_deprecated_macro_use)
1612 Diag(Info.Location, diag::note_pp_macro_annotation) << 0;
1615void Preprocessor::emitRestrictExpansionWarning(
const Token &Identifier)
const {
1616 const MacroAnnotations &A =
1618 assert(A.RestrictExpansionInfo &&
1619 "Macro restricted expansion warning without recorded annotation!");
1620 const MacroAnnotationInfo &Info = *A.RestrictExpansionInfo;
1621 if (Info.Message.empty())
1622 Diag(Identifier, diag::warn_pragma_restrict_expansion_macro_use)
1625 Diag(Identifier, diag::warn_pragma_restrict_expansion_macro_use)
1627 Diag(Info.Location, diag::note_pp_macro_annotation) << 1;
1630void Preprocessor::emitRestrictInfNaNWarning(
const Token &Identifier,
1631 unsigned DiagSelection)
const {
1632 Diag(Identifier, diag::warn_fp_nan_inf_when_disabled) << DiagSelection << 1;
1635void Preprocessor::emitFinalMacroWarning(
const Token &Identifier,
1636 bool IsUndef)
const {
1637 const MacroAnnotations &A =
1639 assert(A.FinalAnnotationLoc &&
1640 "Final macro warning without recorded annotation!");
1642 Diag(Identifier, diag::warn_pragma_final_macro)
1644 Diag(*A.FinalAnnotationLoc, diag::note_pp_macro_annotation) << 2;
1651 auto TestInMap = [&SourceMgr](
const SafeBufferOptOutRegionsTy &Map,
1654 auto FirstRegionEndingAfterLoc = llvm::partition_point(
1656 &Loc](
const std::pair<SourceLocation, SourceLocation> &Region) {
1657 return SourceMgr.isBeforeInTranslationUnit(Region.second, Loc);
1660 if (FirstRegionEndingAfterLoc != Map.end()) {
1662 return SourceMgr.isBeforeInTranslationUnit(
1663 FirstRegionEndingAfterLoc->first, Loc);
1667 if (!Map.empty() && Map.back().first == Map.back().second)
1668 return SourceMgr.isBeforeInTranslationUnit(Map.back().first, Loc);
1690 if (SourceMgr.isLocalSourceLocation(Loc))
1691 return TestInMap(SafeBufferOptOutMap, Loc);
1694 LoadedSafeBufferOptOutMap.lookupLoadedOptOutMap(Loc, SourceMgr);
1706 InSafeBufferOptOutRegion =
true;
1707 CurrentSafeBufferOptOutStart = Loc;
1711 if (!SafeBufferOptOutMap.empty()) {
1712 [[maybe_unused]]
auto *PrevRegion = &SafeBufferOptOutMap.back();
1713 assert(PrevRegion->first != PrevRegion->second &&
1714 "Shall not begin a safe buffer opt-out region before closing the "
1720 SafeBufferOptOutMap.emplace_back(Loc, Loc);
1724 InSafeBufferOptOutRegion =
false;
1728 assert(!SafeBufferOptOutMap.empty() &&
1729 "Misordered safe buffer opt-out regions");
1730 auto *CurrRegion = &SafeBufferOptOutMap.back();
1731 assert(CurrRegion->first == CurrRegion->second &&
1732 "Set end location to a closed safe buffer opt-out region");
1733 CurrRegion->second = Loc;
1739 return InSafeBufferOptOutRegion;
1742 StartLoc = CurrentSafeBufferOptOutStart;
1743 return InSafeBufferOptOutRegion;
1748 assert(!InSafeBufferOptOutRegion &&
1749 "Attempt to serialize safe buffer opt-out regions before file being "
1750 "completely preprocessed");
1754 for (
const auto &[begin, end] : SafeBufferOptOutMap) {
1755 SrcSeq.push_back(begin);
1756 SrcSeq.push_back(end);
1768 if (SourceLocations.size() == 0)
1771 assert(SourceLocations.size() % 2 == 0 &&
1772 "ill-formed SourceLocation sequence");
1774 auto It = SourceLocations.begin();
1775 SafeBufferOptOutRegionsTy &Regions =
1776 LoadedSafeBufferOptOutMap.findAndConsLoadedOptOutMap(*It, SourceMgr);
1782 Regions.emplace_back(Begin, End);
1783 }
while (It != SourceLocations.end());
1805 return C == Record ||
C == DirTracer;
1810 for (
auto *P : Released)
1815 if (
auto It = CheckPoints.find(FID); It != CheckPoints.end()) {
1817 auto P = llvm::upper_bound(FileCheckPoints, Start);
1818 if (P == FileCheckPoints.begin())
1820 return *std::prev(P);
1826 return DirTracer && DirTracer->hasSeenNoTrivialPPDirective();
1830 return SeenNoTrivialPPDirective;
1833void NoTrivialPPDirectiveTracer::setSeenNoTrivialPPDirective() {
1834 if (InMainFile && !SeenNoTrivialPPDirective)
1835 SeenNoTrivialPPDirective =
true;
1841 InMainFile = (FID == PP.getSourceManager().getMainFileID());
1850 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 ...
LLVM_INSTANTIATE_REGISTRY_EX(CLANG_ABI_EXPORT, clang::tooling::ToolExecutorPluginRegistry) namespace clang
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.
bool isModuleKeyword() const
Determine whether this is the contextual keyword module.
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.
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,...
This interface provides a way to observe the actions of the preprocessor as it does its thing.
static void releaseIfPreserved(std::unique_ptr< PPCallbacks > &CB, llvm::function_ref< bool(PPCallbacks *)> Pred, SmallVectorImpl< PPCallbacks * > &Released)
Walk the subtree rooted at CB (recursing into descendants first), then check CB itself.
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.
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
llvm::iterator_range< macro_iterator > macros(bool IncludeExternalMacros=true) 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.
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.
SourceLocation CheckEndOfDirective(StringRef DirType, bool EnableMacros=false, SmallVectorImpl< Token > *ExtraToks=nullptr)
Ensure that the next token is a tok::eod token.
bool getCommentRetentionState() const
Module * getCurrentModuleImplementation()
Retrieves the module whose implementation we're current compiling, if any.
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()
bool LexModuleNameContinue(Token &Tok, SourceLocation UseLoc, SmallVectorImpl< Token > &Suffix, SmallVectorImpl< IdentifierLoc > &Path, bool AllowMacroExpansion, bool IsPartition)
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.
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.
bool HandleModuleName(StringRef DirType, SourceLocation UseLoc, Token &Tok, SmallVectorImpl< IdentifierLoc > &Path, SmallVectorImpl< Token > &DirToks, bool AllowMacroExpansion, bool IsPartition)
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)
Represents an unpacked "presumed" location which can be presented to the user.
unsigned getColumn() const
Return the presumed column number 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.
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'...
Top level wrappers for InstallAPI frontend operations.
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.
ModuleUnitKind
Describes how a source input starts a C++20 module unit.
@ NamedModuleWithoutGlobalModuleFragment
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.
ModuleUnitKind scanInputForCXX20ModuleUnit(StringRef Source)
Scan an input source buffer to determine whether it starts a C++20 module unit, and whether that modu...