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)
83 << std::string(SourceMgr.getBufferName(FileStart)) <<
"";
88 SourceMgr.getFileEntryForID(FID) == CodeCompletionFile) {
89 CodeCompletionFileLoc = SourceMgr.getLocForStartOfFile(FID);
91 CodeCompletionFileLoc.getLocWithOffset(CodeCompletionOffset);
94 Lexer *TheLexer =
new Lexer(FID, *InputFile, *
this, IsFirstIncludeOfFile);
95 if (GetDependencyDirectives && FID != PredefinesFileID)
97 if (
auto MaybeDepDirectives = (*GetDependencyDirectives)(*
File))
98 TheLexer->DepDirectives = *MaybeDepDirectives;
100 EnterSourceFileWithLexer(TheLexer, CurDir);
106void Preprocessor::EnterSourceFileWithLexer(
Lexer *TheLexer,
111 if (CurPPLexer || CurTokenLexer)
112 PushIncludeMacroStack();
114 CurLexer.reset(TheLexer);
115 CurPPLexer = TheLexer;
116 CurDirLookup = CurDir;
117 CurLexerSubmodule =
nullptr;
118 if (CurLexerCallback != CLK_LexAfterModuleImport)
119 CurLexerCallback = TheLexer->isDependencyDirectivesLexer()
120 ? CLK_DependencyDirectivesLexer
124 if (Callbacks && !CurLexer->Is_PragmaLexer) {
126 SourceMgr.getFileCharacteristic(CurLexer->getFileLoc());
136 Callbacks->LexedFileChanged(CurLexer->getFileID(),
146 std::unique_ptr<TokenLexer> TokLexer;
147 if (NumCachedTokenLexers == 0) {
148 TokLexer = std::make_unique<TokenLexer>(
Tok, ILEnd,
Macro, Args, *
this);
150 TokLexer = std::move(TokenLexerCache[--NumCachedTokenLexers]);
151 TokLexer->Init(
Tok, ILEnd,
Macro, Args);
154 PushIncludeMacroStack();
155 CurDirLookup =
nullptr;
156 CurTokenLexer = std::move(TokLexer);
157 if (CurLexerCallback != CLK_LexAfterModuleImport)
158 CurLexerCallback = CLK_TokenLexer;
173void Preprocessor::EnterTokenStream(
const Token *Toks,
unsigned NumToks,
174 bool DisableMacroExpansion,
bool OwnsTokens,
176 if (CurLexerCallback == CLK_CachingLexer) {
178 assert(IsReinject &&
"new tokens in the middle of cached stream");
182 Toks, Toks + NumToks);
190 ExitCachingLexMode();
191 EnterTokenStream(Toks, NumToks, DisableMacroExpansion, OwnsTokens,
193 EnterCachingLexMode();
198 std::unique_ptr<TokenLexer> TokLexer;
199 if (NumCachedTokenLexers == 0) {
200 TokLexer = std::make_unique<TokenLexer>(
201 Toks, NumToks, DisableMacroExpansion, OwnsTokens, IsReinject, *
this);
203 TokLexer = std::move(TokenLexerCache[--NumCachedTokenLexers]);
204 TokLexer->Init(Toks, NumToks, DisableMacroExpansion, OwnsTokens,
209 PushIncludeMacroStack();
210 CurDirLookup =
nullptr;
211 CurTokenLexer = std::move(TokLexer);
212 if (CurLexerCallback != CLK_LexAfterModuleImport)
213 CurLexerCallback = CLK_TokenLexer;
222 StringRef FilePath =
File.getDir().getName();
223 StringRef Path = FilePath;
224 while (!Path.empty()) {
226 if (*CurDir == Dir) {
227 Result = FilePath.substr(Path.size());
228 llvm::sys::path::append(Result,
229 llvm::sys::path::filename(
File.getName()));
234 Path = llvm::sys::path::parent_path(Path);
237 Result =
File.getName();
240void Preprocessor::PropagateLineStartLeadingSpaceInfo(
Token &
Result) {
242 CurTokenLexer->PropagateLineStartLeadingSpaceInfo(
Result);
246 CurLexer->PropagateLineStartLeadingSpaceInfo(
Result);
259const char *Preprocessor::getCurLexerEndPos() {
260 const char *EndPos = CurLexer->BufferEnd;
261 if (EndPos != CurLexer->BufferStart &&
262 (EndPos[-1] ==
'\n' || EndPos[-1] ==
'\r')) {
266 if (EndPos != CurLexer->BufferStart &&
267 (EndPos[-1] ==
'\n' || EndPos[-1] ==
'\r') &&
268 EndPos[-1] != EndPos[0])
278 SubMods.push_back(&Mod);
283void Preprocessor::diagnoseMissingHeaderInUmbrellaDir(
const Module &Mod) {
284 std::optional<Module::Header> UmbrellaHeader =
286 assert(UmbrellaHeader &&
"Module must use umbrella header");
287 const FileID &
File = SourceMgr.translateFile(UmbrellaHeader->Entry);
288 SourceLocation ExpectedHeadersLoc = SourceMgr.getLocForEndOfFile(
File);
289 if (
getDiagnostics().isIgnored(diag::warn_uncovered_module_header,
295 llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
297 for (llvm::vfs::recursive_directory_iterator Entry(FS, Dir->
getName(), EC),
299 Entry != End && !EC; Entry.increment(EC)) {
300 using llvm::StringSwitch;
304 if (!StringSwitch<bool>(llvm::sys::path::extension(Entry->path()))
305 .Cases({
".h",
".H",
".hh",
".hpp"},
true)
309 if (
auto Header =
getFileManager().getOptionalFileRef(Entry->path()))
313 SmallString<128> RelativePath;
315 Diag(ExpectedHeadersLoc, diag::warn_uncovered_module_header)
326 assert(!CurTokenLexer &&
327 "Ending a file when currently in a macro!");
331 if (IncludeMacroStack.empty() &&
335 Diag(UnclosedSafeBufferOptOutLoc,
336 diag::err_pp_unclosed_pragma_unsafe_buffer_usage);
340 const bool LeavingSubmodule = CurLexer && CurLexerSubmodule;
341 if ((LeavingSubmodule || IncludeMacroStack.empty()) &&
342 !BuildingSubmoduleStack.empty() &&
343 BuildingSubmoduleStack.back().IsPragma) {
344 Diag(BuildingSubmoduleStack.back().ImportLoc,
345 diag::err_pp_module_begin_without_module_end);
349 const char *EndPos = getCurLexerEndPos();
350 CurLexer->BufferPtr = EndPos;
351 CurLexer->FormTokenWithChars(
Result, EndPos, tok::annot_module_end);
353 Result.setAnnotationValue(M);
360 CurPPLexer->MIOpt.GetControllingMacroAtEndOfFile()) {
363 HeaderInfo.SetFileControllingMacro(*FE, ControllingMacro);
365 MI->setUsedForHeaderGuard(
true);
367 CurPPLexer->MIOpt.GetDefinedMacro()) {
369 DefinedMacro != ControllingMacro &&
370 CurLexer->isFirstTimeLexingFile()) {
378 const StringRef ControllingMacroName = ControllingMacro->getName();
379 const StringRef DefinedMacroName = DefinedMacro->getName();
380 const size_t MaxHalfLength = std::max(ControllingMacroName.size(),
381 DefinedMacroName.size()) / 2;
382 const unsigned ED = ControllingMacroName.edit_distance(
383 DefinedMacroName,
true, MaxHalfLength);
384 if (ED <= MaxHalfLength) {
386 Diag(CurPPLexer->MIOpt.GetMacroLocation(),
387 diag::warn_header_guard)
388 << CurPPLexer->MIOpt.GetMacroLocation() << ControllingMacro;
389 Diag(CurPPLexer->MIOpt.GetDefinedLocation(),
390 diag::note_header_guard)
391 << CurPPLexer->MIOpt.GetDefinedLocation() << DefinedMacro
394 CurPPLexer->MIOpt.GetDefinedLocation(),
395 ControllingMacro->getName());
406 if (PragmaARCCFCodeAuditedInfo.getLoc().isValid() && !isEndOfMacro &&
407 !(CurLexer && CurLexer->Is_PragmaLexer)) {
408 Diag(PragmaARCCFCodeAuditedInfo.getLoc(),
409 diag::err_pp_eof_in_arc_cf_code_audited);
418 if (PragmaAssumeNonNullLoc.isValid() &&
419 !isEndOfMacro && !(CurLexer && CurLexer->Is_PragmaLexer)) {
424 PreambleRecordedPragmaAssumeNonNullLoc = PragmaAssumeNonNullLoc;
426 Diag(PragmaAssumeNonNullLoc, diag::err_pp_eof_in_assume_nonnull);
431 bool LeavingPCHThroughHeader =
false;
435 if (!IncludeMacroStack.empty()) {
439 SourceMgr.getLocForStartOfFile(CurPPLexer->getFileID()) ==
440 CodeCompletionFileLoc) {
441 assert(CurLexer &&
"Got EOF but no current lexer set!");
443 CurLexer->FormTokenWithChars(
Result, CurLexer->BufferEnd, tok::eof);
444 PendingDestroyLexers.push_back(std::move(CurLexer));
446 CurPPLexer =
nullptr;
451 if (!isEndOfMacro && CurPPLexer &&
452 (SourceMgr.getIncludeLoc(CurPPLexer->getFileID()).isValid() ||
454 (PredefinesFileID.isValid() &&
455 CurPPLexer->getFileID() == PredefinesFileID))) {
459 SourceMgr.local_sloc_entry_size() -
460 CurPPLexer->getInitialNumSLocEntries() + 1;
461 SourceMgr.setNumCreatedFIDsForFileID(CurPPLexer->getFileID(), NumFIDs);
464 bool ExitedFromPredefinesFile =
false;
466 if (!isEndOfMacro && CurPPLexer) {
467 ExitedFID = CurPPLexer->getFileID();
469 assert(PredefinesFileID.isValid() &&
470 "HandleEndOfFile is called before PredefinesFileId is set");
471 ExitedFromPredefinesFile = (PredefinesFileID == ExitedFID);
474 if (LeavingSubmodule) {
479 const char *EndPos = getCurLexerEndPos();
481 CurLexer->BufferPtr = EndPos;
482 CurLexer->FormTokenWithChars(
Result, EndPos, tok::annot_module_end);
484 Result.setAnnotationValue(M);
487 bool FoundPCHThroughHeader =
false;
490 SourceMgr.getFileEntryForID(CurPPLexer->getFileID())))
491 FoundPCHThroughHeader =
true;
497 PropagateLineStartLeadingSpaceInfo(
Result);
500 if (Callbacks && !isEndOfMacro && CurPPLexer) {
503 SourceMgr.getFileCharacteristic(Loc);
505 Callbacks->LexedFileChanged(CurPPLexer->getFileID(),
507 FileType, ExitedFID, Loc);
513 if (ExitedFromPredefinesFile) {
514 replayPreambleConditionalStack();
515 if (PreambleRecordedPragmaAssumeNonNullLoc.isValid())
516 PragmaAssumeNonNullLoc = PreambleRecordedPragmaAssumeNonNullLoc;
519 if (!isEndOfMacro && CurPPLexer && FoundPCHThroughHeader &&
524 LeavingPCHThroughHeader =
true;
527 return LeavingSubmodule;
531 assert(CurLexer &&
"Got EOF but no current lexer set!");
532 const char *EndPos = getCurLexerEndPos();
534 CurLexer->BufferPtr = EndPos;
537 CurLexer->FormTokenWithChars(
Result, EndPos, tok::annot_repl_input_end);
539 Result.setAnnotationValue(
nullptr);
541 CurLexer->FormTokenWithChars(
Result, EndPos, tok::eof);
551 if (CurLexer->getFileLoc() == CodeCompletionFileLoc)
552 Result.setLocation(
Result.getLocation().getLocWithOffset(-1));
557 Diag(CurLexer->getFileLoc(), diag::err_pp_through_header_not_seen)
558 << PPOpts.PCHThroughHeader << 0;
566 if (LexLevel > 0 && CurLexer) {
567 PendingDestroyLexers.push_back(std::move(CurLexer));
574 CurPPLexer =
nullptr;
580 for (WarnUnusedMacroLocsTy::iterator
581 I=WarnUnusedMacroLocs.begin(), E=WarnUnusedMacroLocs.end();
583 Diag(*I, diag::pp_macro_not_used);
593 for (
auto *M : AllMods)
594 diagnoseMissingHeaderInUmbrellaDir(*M);
603 assert(CurTokenLexer && !CurPPLexer &&
604 "Ending a macro when currently in a #include file!");
606 if (!MacroExpandingLexersStack.empty() &&
607 MacroExpandingLexersStack.back().first == CurTokenLexer.get())
608 removeCachedMacroExpandedTokensOfLastLexer();
611 if (NumCachedTokenLexers == TokenLexerCacheSize)
612 CurTokenLexer.reset();
614 TokenLexerCache[NumCachedTokenLexers++] = std::move(CurTokenLexer);
624 assert(!IncludeMacroStack.empty() &&
"Ran out of stack entries to load");
628 if (NumCachedTokenLexers == TokenLexerCacheSize)
629 CurTokenLexer.reset();
631 TokenLexerCache[NumCachedTokenLexers++] = std::move(CurTokenLexer);
634 PopIncludeMacroStack();
641 assert(CurTokenLexer && !CurPPLexer &&
642 "Pasted comment can only be formed from macro");
647 bool LexerWasInPPMode =
false;
648 for (
const IncludeStackInfo &ISI : llvm::reverse(IncludeMacroStack)) {
649 if (ISI.ThePPLexer ==
nullptr)
continue;
657 FoundLexer = ISI.ThePPLexer;
675 while (
Tok.isNot(tok::eod) &&
Tok.isNot(tok::eof))
679 if (
Tok.is(tok::eod)) {
680 assert(FoundLexer &&
"Can't get end of line without an active lexer");
686 if (LexerWasInPPMode)
return;
697 assert(!FoundLexer &&
"Lexer should return EOD before EOF in PP mode");
704 BuildingSubmoduleStack.push_back(
705 BuildingSubmoduleInfo(M, ImportLoc, ForPragma, CurSubmoduleState,
706 PendingModuleMacroNames.size()));
708 Callbacks->EnteredSubmodule(M, ImportLoc, ForPragma);
722 auto R = Submodules.try_emplace(M);
723 auto &State = R.first->second;
724 bool FirstTime = R.second;
732 auto &StartingMacros = NullSubmoduleState.Macros;
736 for (
auto &
Macro : StartingMacros) {
738 if (!
Macro.second.getLatest() &&
739 Macro.second.getOverriddenMacros().empty())
742 MacroState MS(
Macro.second.getLatest());
743 MS.setOverriddenMacros(*
this,
Macro.second.getOverriddenMacros());
744 State.Macros.insert(std::make_pair(
Macro.first, std::move(MS)));
749 BuildingSubmoduleStack.push_back(
750 BuildingSubmoduleInfo(M, ImportLoc, ForPragma, CurSubmoduleState,
751 PendingModuleMacroNames.size()));
754 Callbacks->EnteredSubmodule(M, ImportLoc, ForPragma);
757 CurSubmoduleState = &State;
765bool Preprocessor::needModuleMacros()
const {
767 if (BuildingSubmoduleStack.empty())
779 if (BuildingSubmoduleStack.empty() ||
780 BuildingSubmoduleStack.back().IsPragma != ForPragma) {
781 assert(ForPragma &&
"non-pragma module enter/leave mismatch");
785 auto &Info = BuildingSubmoduleStack.back();
787 Module *LeavingMod = Info.M;
790 if (!needModuleMacros() ||
796 BuildingSubmoduleStack.pop_back();
799 Callbacks->LeftSubmodule(LeavingMod, ImportLoc, ForPragma);
807 for (
unsigned I = Info.OuterPendingModuleMacroNames;
808 I != PendingModuleMacroNames.size(); ++I) {
809 auto *II = PendingModuleMacroNames[I];
810 if (!VisitedMacros.insert(II).second)
813 auto MacroIt = CurSubmoduleState->Macros.find(II);
814 if (MacroIt == CurSubmoduleState->Macros.end())
816 auto &
Macro = MacroIt->second;
820 auto *OldState = Info.OuterSubmoduleState;
822 OldState = &NullSubmoduleState;
823 if (OldState && OldState != CurSubmoduleState) {
826 auto &OldMacros = OldState->Macros;
827 auto OldMacroIt = OldMacros.find(II);
828 if (OldMacroIt == OldMacros.end())
831 OldMD = OldMacroIt->second.getLatest();
836 bool ExplicitlyPublic =
false;
838 assert(MD &&
"broken macro directive chain");
840 if (
auto *VisMD = dyn_cast<VisibilityMacroDirective>(MD)) {
843 if (VisMD->isPublic())
844 ExplicitlyPublic =
true;
845 else if (!ExplicitlyPublic)
851 Def = DefMD->getInfo();
858 if (Def || !
Macro.getOverriddenMacros().empty())
865 Macro.setLatest(
nullptr);
866 Macro.setOverriddenMacros(*
this, {});
872 PendingModuleMacroNames.resize(Info.OuterPendingModuleMacroNames);
881 CurSubmoduleState = Info.OuterSubmoduleState;
883 BuildingSubmoduleStack.pop_back();
886 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.
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.
A simple pair of identifier info and location.
bool isCompilingModule() const
Are we compiling a module?
Lexer - This provides a simple interface that turns a text buffer into a stream of tokens.
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...
bool LexingRawMode
True if in raw mode.
bool ParsingPreprocessorDirective
True when parsing #XXX; turns '\n' into a tok::eod token.
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 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()
void makeModuleVisible(Module *M, SourceLocation Loc, bool IncludeExports=true)
FileManager & getFileManager() const
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.
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.
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.
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
detail::SearchDirIteratorImpl< true > ConstSearchDirIterator
@ Result
The result type of a method or function.
@ TU_Complete
The translation unit is a complete translation unit.
CustomizableOptional< DirectoryEntryRef > OptionalDirectoryEntryRef
SmallVector< Token, 4 > CachedTokens
A set of tokens that has been cached for later parsing.