21#include "llvm/ADT/StringSwitch.h"
22#include "llvm/Support/MemoryBufferRef.h"
23#include "llvm/Support/Path.h"
36 return IncludeMacroStack.empty();
39 assert(IsFileLexer(IncludeMacroStack[0]) &&
40 "Top level include stack isn't our primary lexer?");
42 llvm::drop_begin(IncludeMacroStack),
43 [&](
const IncludeStackInfo &ISI) ->
bool {
return IsFileLexer(ISI); });
54 for (
const IncludeStackInfo &ISI : llvm::reverse(IncludeMacroStack)) {
56 return ISI.ThePPLexer;
70 bool IsFirstIncludeOfFile) {
71 assert(!CurTokenLexer &&
"Cannot #include a file inside a macro!");
72 ++NumEnteredSourceFiles;
74 if (MaxIncludeStackDepth < IncludeMacroStack.size())
75 MaxIncludeStackDepth = IncludeMacroStack.size();
78 std::optional<llvm::MemoryBufferRef> InputFile =
82 Diag(
Loc, diag::err_pp_error_opening_file)
94 Lexer *TheLexer =
new Lexer(FID, *InputFile, *
this, IsFirstIncludeOfFile);
96 FID != PredefinesFileID) {
101 TheLexer->DepDirectives = *DepDirectives;
106 EnterSourceFileWithLexer(TheLexer, CurDir);
112void Preprocessor::EnterSourceFileWithLexer(
Lexer *TheLexer,
117 if (CurPPLexer || CurTokenLexer)
118 PushIncludeMacroStack();
120 CurLexer.reset(TheLexer);
121 CurPPLexer = TheLexer;
122 CurDirLookup = CurDir;
123 CurLexerSubmodule =
nullptr;
124 if (CurLexerCallback != CLK_LexAfterModuleImport)
125 CurLexerCallback = TheLexer->isDependencyDirectivesLexer()
126 ? CLK_DependencyDirectivesLexer
130 if (Callbacks && !CurLexer->Is_PragmaLexer) {
142 Callbacks->LexedFileChanged(CurLexer->getFileID(),
152 std::unique_ptr<TokenLexer> TokLexer;
153 if (NumCachedTokenLexers == 0) {
154 TokLexer = std::make_unique<TokenLexer>(Tok, ILEnd, Macro, Args, *
this);
156 TokLexer = std::move(TokenLexerCache[--NumCachedTokenLexers]);
157 TokLexer->Init(Tok, ILEnd, Macro, Args);
160 PushIncludeMacroStack();
161 CurDirLookup =
nullptr;
162 CurTokenLexer = std::move(TokLexer);
163 if (CurLexerCallback != CLK_LexAfterModuleImport)
164 CurLexerCallback = CLK_TokenLexer;
179void Preprocessor::EnterTokenStream(
const Token *Toks,
unsigned NumToks,
180 bool DisableMacroExpansion,
bool OwnsTokens,
182 if (CurLexerCallback == CLK_CachingLexer) {
184 assert(IsReinject &&
"new tokens in the middle of cached stream");
188 Toks, Toks + NumToks);
196 ExitCachingLexMode();
197 EnterTokenStream(Toks, NumToks, DisableMacroExpansion, OwnsTokens,
199 EnterCachingLexMode();
204 std::unique_ptr<TokenLexer> TokLexer;
205 if (NumCachedTokenLexers == 0) {
206 TokLexer = std::make_unique<TokenLexer>(
207 Toks, NumToks, DisableMacroExpansion, OwnsTokens, IsReinject, *
this);
209 TokLexer = std::move(TokenLexerCache[--NumCachedTokenLexers]);
210 TokLexer->Init(Toks, NumToks, DisableMacroExpansion, OwnsTokens,
215 PushIncludeMacroStack();
216 CurDirLookup =
nullptr;
217 CurTokenLexer = std::move(TokLexer);
218 if (CurLexerCallback != CLK_LexAfterModuleImport)
219 CurLexerCallback = CLK_TokenLexer;
228 StringRef FilePath =
File.getDir().getName();
229 StringRef
Path = FilePath;
230 while (!
Path.empty()) {
232 if (*CurDir == Dir) {
234 llvm::sys::path::append(
Result,
235 llvm::sys::path::filename(
File.getName()));
240 Path = llvm::sys::path::parent_path(
Path);
246void Preprocessor::PropagateLineStartLeadingSpaceInfo(
Token &
Result) {
248 CurTokenLexer->PropagateLineStartLeadingSpaceInfo(
Result);
252 CurLexer->PropagateLineStartLeadingSpaceInfo(
Result);
265const char *Preprocessor::getCurLexerEndPos() {
266 const char *EndPos = CurLexer->BufferEnd;
267 if (EndPos != CurLexer->BufferStart &&
268 (EndPos[-1] ==
'\n' || EndPos[-1] ==
'\r')) {
272 if (EndPos != CurLexer->BufferStart &&
273 (EndPos[-1] ==
'\n' || EndPos[-1] ==
'\r') &&
274 EndPos[-1] != EndPos[0])
284 SubMods.push_back(&Mod);
289void Preprocessor::diagnoseMissingHeaderInUmbrellaDir(
const Module &Mod) {
290 std::optional<Module::Header> UmbrellaHeader =
292 assert(UmbrellaHeader &&
"Module must use umbrella header");
295 if (
getDiagnostics().isIgnored(diag::warn_uncovered_module_header,
303 for (llvm::vfs::recursive_directory_iterator Entry(FS, Dir->
getName(), EC),
305 Entry != End && !EC; Entry.increment(EC)) {
306 using llvm::StringSwitch;
310 if (!StringSwitch<bool>(llvm::sys::path::extension(Entry->path()))
311 .Cases(
".h",
".H",
".hh",
".hpp",
true)
315 if (
auto Header =
getFileManager().getOptionalFileRef(Entry->path()))
321 Diag(ExpectedHeadersLoc, diag::warn_uncovered_module_header)
332 assert(!CurTokenLexer &&
333 "Ending a file when currently in a macro!");
337 if (IncludeMacroStack.empty() &&
341 Diag(UnclosedSafeBufferOptOutLoc,
342 diag::err_pp_unclosed_pragma_unsafe_buffer_usage);
346 const bool LeavingSubmodule = CurLexer && CurLexerSubmodule;
347 if ((LeavingSubmodule || IncludeMacroStack.empty()) &&
348 !BuildingSubmoduleStack.empty() &&
349 BuildingSubmoduleStack.back().IsPragma) {
350 Diag(BuildingSubmoduleStack.back().ImportLoc,
351 diag::err_pp_module_begin_without_module_end);
355 const char *EndPos = getCurLexerEndPos();
356 CurLexer->BufferPtr = EndPos;
357 CurLexer->FormTokenWithChars(
Result, EndPos, tok::annot_module_end);
359 Result.setAnnotationValue(M);
371 MI->setUsedForHeaderGuard(
true);
375 DefinedMacro != ControllingMacro &&
376 CurLexer->isFirstTimeLexingFile()) {
384 const StringRef ControllingMacroName = ControllingMacro->getName();
385 const StringRef DefinedMacroName = DefinedMacro->getName();
386 const size_t MaxHalfLength = std::max(ControllingMacroName.size(),
387 DefinedMacroName.size()) / 2;
388 const unsigned ED = ControllingMacroName.edit_distance(
389 DefinedMacroName,
true, MaxHalfLength);
390 if (ED <= MaxHalfLength) {
393 diag::warn_header_guard)
396 diag::note_header_guard)
401 ControllingMacro->getName());
412 if (PragmaARCCFCodeAuditedInfo.second.isValid() && !isEndOfMacro &&
413 !(CurLexer && CurLexer->Is_PragmaLexer)) {
414 Diag(PragmaARCCFCodeAuditedInfo.second,
415 diag::err_pp_eof_in_arc_cf_code_audited);
424 if (PragmaAssumeNonNullLoc.
isValid() &&
425 !isEndOfMacro && !(CurLexer && CurLexer->Is_PragmaLexer)) {
430 PreambleRecordedPragmaAssumeNonNullLoc = PragmaAssumeNonNullLoc;
432 Diag(PragmaAssumeNonNullLoc, diag::err_pp_eof_in_assume_nonnull);
437 bool LeavingPCHThroughHeader =
false;
441 if (!IncludeMacroStack.empty()) {
446 CodeCompletionFileLoc) {
447 assert(CurLexer &&
"Got EOF but no current lexer set!");
449 CurLexer->FormTokenWithChars(
Result, CurLexer->BufferEnd, tok::eof);
452 CurPPLexer =
nullptr;
457 if (!isEndOfMacro && CurPPLexer &&
461 CurPPLexer->
getFileID() == PredefinesFileID))) {
470 bool ExitedFromPredefinesFile =
false;
472 if (!isEndOfMacro && CurPPLexer) {
475 assert(PredefinesFileID.
isValid() &&
476 "HandleEndOfFile is called before PredefinesFileId is set");
477 ExitedFromPredefinesFile = (PredefinesFileID == ExitedFID);
480 if (LeavingSubmodule) {
485 const char *EndPos = getCurLexerEndPos();
487 CurLexer->BufferPtr = EndPos;
488 CurLexer->FormTokenWithChars(
Result, EndPos, tok::annot_module_end);
490 Result.setAnnotationValue(M);
493 bool FoundPCHThroughHeader =
false;
497 FoundPCHThroughHeader =
true;
503 PropagateLineStartLeadingSpaceInfo(
Result);
506 if (Callbacks && !isEndOfMacro && CurPPLexer) {
511 Callbacks->LexedFileChanged(CurPPLexer->
getFileID(),
519 if (ExitedFromPredefinesFile) {
520 replayPreambleConditionalStack();
521 if (PreambleRecordedPragmaAssumeNonNullLoc.
isValid())
522 PragmaAssumeNonNullLoc = PreambleRecordedPragmaAssumeNonNullLoc;
525 if (!isEndOfMacro && CurPPLexer && FoundPCHThroughHeader &&
530 LeavingPCHThroughHeader =
true;
533 return LeavingSubmodule;
537 assert(CurLexer &&
"Got EOF but no current lexer set!");
538 const char *EndPos = getCurLexerEndPos();
540 CurLexer->BufferPtr = EndPos;
543 CurLexer->FormTokenWithChars(
Result, EndPos, tok::annot_repl_input_end);
545 Result.setAnnotationValue(
nullptr);
547 CurLexer->FormTokenWithChars(
Result, EndPos, tok::eof);
557 if (CurLexer->getFileLoc() == CodeCompletionFileLoc)
558 Result.setLocation(
Result.getLocation().getLocWithOffset(-1));
563 Diag(CurLexer->getFileLoc(), diag::err_pp_through_header_not_seen)
564 << PPOpts->PCHThroughHeader << 0;
572 CurPPLexer =
nullptr;
578 for (WarnUnusedMacroLocsTy::iterator
579 I=WarnUnusedMacroLocs.begin(),
E=WarnUnusedMacroLocs.end();
581 Diag(*I, diag::pp_macro_not_used);
591 for (
auto *M : AllMods)
592 diagnoseMissingHeaderInUmbrellaDir(*M);
601 assert(CurTokenLexer && !CurPPLexer &&
602 "Ending a macro when currently in a #include file!");
604 if (!MacroExpandingLexersStack.empty() &&
605 MacroExpandingLexersStack.back().first == CurTokenLexer.get())
606 removeCachedMacroExpandedTokensOfLastLexer();
609 if (NumCachedTokenLexers == TokenLexerCacheSize)
610 CurTokenLexer.reset();
612 TokenLexerCache[NumCachedTokenLexers++] = std::move(CurTokenLexer);
622 assert(!IncludeMacroStack.empty() &&
"Ran out of stack entries to load");
626 if (NumCachedTokenLexers == TokenLexerCacheSize)
627 CurTokenLexer.reset();
629 TokenLexerCache[NumCachedTokenLexers++] = std::move(CurTokenLexer);
632 PopIncludeMacroStack();
639 assert(CurTokenLexer && !CurPPLexer &&
640 "Pasted comment can only be formed from macro");
645 bool LexerWasInPPMode =
false;
646 for (
const IncludeStackInfo &ISI : llvm::reverse(IncludeMacroStack)) {
647 if (ISI.ThePPLexer ==
nullptr)
continue;
655 FoundLexer = ISI.ThePPLexer;
673 while (Tok.
isNot(tok::eod) && Tok.
isNot(tok::eof))
677 if (Tok.
is(tok::eod)) {
678 assert(FoundLexer &&
"Can't get end of line without an active lexer");
684 if (LexerWasInPPMode)
return;
695 assert(!FoundLexer &&
"Lexer should return EOD before EOF in PP mode");
702 BuildingSubmoduleStack.push_back(
703 BuildingSubmoduleInfo(M, ImportLoc, ForPragma, CurSubmoduleState,
704 PendingModuleMacroNames.size()));
706 Callbacks->EnteredSubmodule(M, ImportLoc, ForPragma);
720 auto R = Submodules.insert(std::make_pair(M, SubmoduleState()));
721 auto &State = R.first->second;
722 bool FirstTime = R.second;
730 auto &StartingMacros = NullSubmoduleState.Macros;
734 for (
auto &Macro : StartingMacros) {
736 if (!Macro.second.getLatest() &&
737 Macro.second.getOverriddenMacros().empty())
740 MacroState MS(Macro.second.getLatest());
741 MS.setOverriddenMacros(*
this, Macro.second.getOverriddenMacros());
742 State.Macros.insert(std::make_pair(Macro.first, std::move(MS)));
747 BuildingSubmoduleStack.push_back(
748 BuildingSubmoduleInfo(M, ImportLoc, ForPragma, CurSubmoduleState,
749 PendingModuleMacroNames.size()));
752 Callbacks->EnteredSubmodule(M, ImportLoc, ForPragma);
755 CurSubmoduleState = &State;
762bool Preprocessor::needModuleMacros()
const {
764 if (BuildingSubmoduleStack.empty())
776 if (BuildingSubmoduleStack.empty() ||
777 BuildingSubmoduleStack.back().IsPragma != ForPragma) {
778 assert(ForPragma &&
"non-pragma module enter/leave mismatch");
782 auto &Info = BuildingSubmoduleStack.back();
784 Module *LeavingMod = Info.M;
787 if (!needModuleMacros() ||
793 BuildingSubmoduleStack.pop_back();
796 Callbacks->LeftSubmodule(LeavingMod, ImportLoc, ForPragma);
804 for (
unsigned I = Info.OuterPendingModuleMacroNames;
805 I != PendingModuleMacroNames.size(); ++I) {
806 auto *II = PendingModuleMacroNames[I];
807 if (!VisitedMacros.insert(II).second)
810 auto MacroIt = CurSubmoduleState->Macros.find(II);
811 if (MacroIt == CurSubmoduleState->Macros.end())
813 auto &Macro = MacroIt->second;
817 auto *OldState = Info.OuterSubmoduleState;
819 OldState = &NullSubmoduleState;
820 if (OldState && OldState != CurSubmoduleState) {
823 auto &OldMacros = OldState->Macros;
824 auto OldMacroIt = OldMacros.find(II);
825 if (OldMacroIt == OldMacros.end())
828 OldMD = OldMacroIt->second.getLatest();
833 bool ExplicitlyPublic =
false;
834 for (
auto *MD = Macro.getLatest(); MD != OldMD; MD = MD->
getPrevious()) {
835 assert(MD &&
"broken macro directive chain");
837 if (
auto *VisMD = dyn_cast<VisibilityMacroDirective>(MD)) {
840 if (VisMD->isPublic())
841 ExplicitlyPublic =
true;
842 else if (!ExplicitlyPublic)
848 Def = DefMD->getInfo();
855 if (Def || !Macro.getOverriddenMacros().empty())
862 Macro.setLatest(
nullptr);
863 Macro.setOverriddenMacros(*
this, {});
869 PendingModuleMacroNames.resize(Info.OuterPendingModuleMacroNames);
878 CurSubmoduleState = Info.OuterSubmoduleState;
880 BuildingSubmoduleStack.pop_back();
883 Callbacks->LeftSubmodule(LeavingMod, ImportLoc, ForPragma);
Defines the clang::FileManager interface and associated types.
llvm::MachO::FileType FileType
Defines the clang::MacroInfo and clang::MacroDirective classes.
static void collectAllSubModulesWithUmbrellaHeader(const Module &Mod, SmallVectorImpl< const Module * > &SubMods)
static void computeRelativePath(FileManager &FM, const DirectoryEntry *Dir, FileEntryRef File, SmallString< 128 > &Result)
Compute the relative path that names the given file relative to the given directory.
Defines the clang::Preprocessor interface.
Defines the SourceManager interface.
A directive for a defined macro or a macro imported from a module.
StringRef getName() const
Cached information about one directory (either on disk or in the virtual file system).
A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Implements support for file system lookup, file system caching, and directory search management.
llvm::vfs::FileSystem & getVirtualFileSystem() const
OptionalDirectoryEntryRef getOptionalDirectoryRef(StringRef DirName, bool CacheFailure=true)
Get a DirectoryEntryRef if it exists, without doing anything on error.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
One of these records is kept for each identifier that is lexed.
bool isCompilingModule() const
Are we compiling a module?
Lexer - This provides a simple interface that turns a text buffer into a stream of tokens.
MacroArgs - An instance of this class captures information about the formal arguments specified to a ...
Encapsulates changes to the "macros namespace" (the location where the macro name became active,...
const MacroDirective * getPrevious() const
Get previous definition of the macro with the same name.
Encapsulates the data about a macro definition (e.g.
bool resolveExports(Module *Mod, bool Complain)
Resolve all of the unresolved exports in the given module.
bool resolveConflicts(Module *Mod, bool Complain)
Resolve all of the unresolved conflicts in the given module.
bool isHeaderInUnavailableModule(FileEntryRef Header) const
Determine whether the given header is part of a module marked 'unavailable'.
bool resolveUses(Module *Mod, bool Complain)
Resolve all of the unresolved uses in the given module.
Describes a module or submodule.
StringRef getTopLevelModuleName() const
Retrieve the name of the top-level module.
llvm::iterator_range< submodule_iterator > submodules()
std::optional< Header > getUmbrellaHeaderAsWritten() const
Retrieve the umbrella header as written.
std::string getFullModuleName(bool AllowStringLiterals=false) const
Retrieve the full name of this module, including the path from its top-level module.
OptionalDirectoryEntryRef getEffectiveUmbrellaDir() const
Get the effective umbrella directory for this module: either the one explicitly written in the module...
const IdentifierInfo * GetDefinedMacro() const
If the ControllingMacro is followed by a macro definition, return the macro that was defined.
const IdentifierInfo * GetControllingMacroAtEndOfFile() const
Once the entire file has been lexed, if there is a controlling macro, return it.
SourceLocation GetDefinedLocation() const
SourceLocation GetMacroLocation() const
unsigned getInitialNumSLocEntries() const
Number of SLocEntries before lexing the file.
bool LexingRawMode
True if in raw mode.
bool ParsingPreprocessorDirective
True when parsing #XXX; turns '\n' into a tok::eod token.
MultipleIncludeOpt MIOpt
A state machine that detects the #ifndef-wrapping a file idiom for the multiple-include optimization.
OptionalFileEntryRef getFileEntry() const
getFileEntry - Return the FileEntry corresponding to this FileID.
virtual SourceLocation getSourceLocation()=0
Return the source location for the next observable location.
bool creatingPCHWithThroughHeader()
True if creating a PCH with a through header.
ModuleMacro * addModuleMacro(Module *Mod, IdentifierInfo *II, MacroInfo *Macro, ArrayRef< ModuleMacro * > Overrides, bool &IsNew)
Register an exported macro for a module and identifier.
bool isIncrementalProcessingEnabled() const
Returns true if incremental processing is enabled.
const MacroInfo * getMacroInfo(const IdentifierInfo *II) const
bool isRecordingPreamble() const
bool isInPrimaryFile() const
Return true if we're in the top-level file, not in a #include.
void EnterSubmodule(Module *M, SourceLocation ImportLoc, bool ForPragma)
bool HandleEndOfTokenLexer(Token &Result)
Callback invoked when the current TokenLexer hits the end of its token stream.
void makeModuleVisible(Module *M, SourceLocation Loc)
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...
SourceManager & getSourceManager() const
bool isMacroDefined(StringRef Id)
Module * getCurrentModule()
Retrieves the module that we're currently building, if any.
bool isPPInSafeBufferOptOutRegion()
FileManager & getFileManager() const
PreprocessorOptions & getPreprocessorOpts() const
Retrieve the preprocessor options used to initialize this preprocessor.
bool isPCHThroughHeader(const FileEntry *FE)
Returns true if the FileEntry is the PCH through header.
FileID getPredefinesFileID() const
Returns the FileID for the preprocessor predefines.
bool isCodeCompletionEnabled() const
Determine if we are performing code completion.
PreprocessorLexer * getCurrentFileLexer() const
Return the current file lexer being lexed from.
HeaderSearch & getHeaderSearchInfo() const
Module * LeaveSubmodule(bool ForPragma)
void recomputeCurLexerKind()
Recompute the current lexer kind based on the CurLexer/ CurTokenLexer pointers.
const LangOptions & getLangOpts() const
void RemoveTopOfLexerStack()
Pop the current lexer/macro exp off the top of the lexer stack.
bool HandleEndOfFile(Token &Result, bool isEndOfMacro=false)
Callback invoked when the lexer hits the end of the current file.
DiagnosticsEngine & getDiagnostics() const
void EnterMacro(Token &Tok, SourceLocation ILEnd, MacroInfo *Macro, MacroArgs *Args)
Add a Macro to the top of the include stack and start lexing tokens from it instead of the current bu...
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const
Forwarding function for diagnostics.
void HandleMicrosoftCommentPaste(Token &Tok)
When the macro expander pastes together a comment (/##/) in Microsoft mode, this method handles updat...
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
OptionalFileEntryRef getFileEntryRefForID(FileID FID) const
Returns the FileEntryRef for the provided FileID.
StringRef getBufferName(SourceLocation Loc, bool *Invalid=nullptr) const
Return the filename or buffer identifier of the buffer the location is in.
FileID translateFile(const FileEntry *SourceFile) const
Get the FileID for the given file.
unsigned local_sloc_entry_size() const
Get the number of local SLocEntries we have.
SourceLocation getLocForEndOfFile(FileID FID) const
Return the source location corresponding to the last byte of the specified file.
SourceLocation getIncludeLoc(FileID FID) const
Returns the include location if FID is a #include'd file otherwise it returns an invalid location.
void setNumCreatedFIDsForFileID(FileID FID, unsigned NumFIDs, bool Force=false)
Set the number of FileIDs (files and macros) that were created during preprocessing of FID,...
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
SourceLocation getLocForStartOfFile(FileID FID) const
Return the source location corresponding to the first byte of the specified file.
SrcMgr::CharacteristicKind getFileCharacteristic(SourceLocation Loc) const
Return the file characteristic of the specified source location, indicating whether this is a normal ...
std::optional< llvm::MemoryBufferRef > getBufferOrNone(FileID FID, SourceLocation Loc=SourceLocation()) const
Return the buffer for the specified FileID.
Token - This structure provides full information about a lexed token.
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 isNot(tok::TokenKind K) const
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
The JSON file list parser is used to communicate input to InstallAPI.
@ Result
The result type of a method or function.
@ TU_Complete
The translation unit is a complete translation unit.