22 #include "llvm/ADT/StringSwitch.h"
23 #include "llvm/Support/FileSystem.h"
24 #include "llvm/Support/MemoryBuffer.h"
25 #include "llvm/Support/Path.h"
26 using namespace clang;
38 return IncludeMacroStack.empty();
41 assert(IsFileLexer(IncludeMacroStack[0]) &&
42 "Top level include stack isn't our primary lexer?");
43 for (
unsigned i = 1, e = IncludeMacroStack.size(); i != e; ++i)
44 if (IsFileLexer(IncludeMacroStack[i]))
57 for (
unsigned i = IncludeMacroStack.size(); i != 0; --i) {
58 const IncludeStackInfo& ISI = IncludeMacroStack[i-1];
60 return ISI.ThePPLexer;
74 assert(!CurTokenLexer &&
"Cannot #include a file inside a macro!");
75 ++NumEnteredSourceFiles;
77 if (MaxIncludeStackDepth < IncludeMacroStack.size())
78 MaxIncludeStackDepth = IncludeMacroStack.size();
81 if (
PTHLexer *PL = PTH->CreateLexer(FID)) {
82 EnterSourceFileWithPTH(PL, CurDir);
89 const llvm::MemoryBuffer *InputFile =
93 Diag(Loc, diag::err_pp_error_opening_file)
105 EnterSourceFileWithLexer(
new Lexer(FID, InputFile, *
this), CurDir);
111 void Preprocessor::EnterSourceFileWithLexer(
Lexer *TheLexer,
115 if (CurPPLexer || CurTokenLexer)
116 PushIncludeMacroStack();
118 CurLexer.reset(TheLexer);
119 CurPPLexer = TheLexer;
120 CurDirLookup = CurDir;
121 CurSubmodule =
nullptr;
122 if (CurLexerKind != CLK_LexAfterModuleImport)
123 CurLexerKind = CLK_Lexer;
126 if (Callbacks && !CurLexer->Is_PragmaLexer) {
130 Callbacks->FileChanged(CurLexer->getFileLoc(),
137 void Preprocessor::EnterSourceFileWithPTH(
PTHLexer *PL,
140 if (CurPPLexer || CurTokenLexer)
141 PushIncludeMacroStack();
143 CurDirLookup = CurDir;
144 CurPTHLexer.reset(PL);
145 CurPPLexer = CurPTHLexer.get();
146 CurSubmodule =
nullptr;
147 if (CurLexerKind != CLK_LexAfterModuleImport)
148 CurLexerKind = CLK_PTHLexer;
164 std::unique_ptr<TokenLexer> TokLexer;
165 if (NumCachedTokenLexers == 0) {
166 TokLexer = llvm::make_unique<TokenLexer>(Tok, ILEnd, Macro, Args, *
this);
168 TokLexer = std::move(TokenLexerCache[--NumCachedTokenLexers]);
169 TokLexer->Init(Tok, ILEnd, Macro, Args);
172 PushIncludeMacroStack();
173 CurDirLookup =
nullptr;
174 CurTokenLexer = std::move(TokLexer);
175 if (CurLexerKind != CLK_LexAfterModuleImport)
176 CurLexerKind = CLK_TokenLexer;
191 void Preprocessor::EnterTokenStream(
const Token *Toks,
unsigned NumToks,
192 bool DisableMacroExpansion,
194 if (CurLexerKind == CLK_CachingLexer) {
199 Toks, Toks + NumToks);
207 ExitCachingLexMode();
208 EnterTokenStream(Toks, NumToks, DisableMacroExpansion, OwnsTokens);
209 EnterCachingLexMode();
214 std::unique_ptr<TokenLexer> TokLexer;
215 if (NumCachedTokenLexers == 0) {
216 TokLexer = llvm::make_unique<TokenLexer>(
217 Toks, NumToks, DisableMacroExpansion, OwnsTokens, *
this);
219 TokLexer = std::move(TokenLexerCache[--NumCachedTokenLexers]);
220 TokLexer->Init(Toks, NumToks, DisableMacroExpansion, OwnsTokens);
224 PushIncludeMacroStack();
225 CurDirLookup =
nullptr;
226 CurTokenLexer = std::move(TokLexer);
227 if (CurLexerKind != CLK_LexAfterModuleImport)
228 CurLexerKind = CLK_TokenLexer;
240 while (!Path.empty()) {
243 Result = FilePath.substr(Path.size());
244 llvm::sys::path::append(Result,
245 llvm::sys::path::filename(File->
getName()));
250 Path = llvm::sys::path::parent_path(Path);
256 void Preprocessor::PropagateLineStartLeadingSpaceInfo(
Token &Result) {
258 CurTokenLexer->PropagateLineStartLeadingSpaceInfo(Result);
262 CurLexer->PropagateLineStartLeadingSpaceInfo(Result);
275 const char *Preprocessor::getCurLexerEndPos() {
276 const char *EndPos = CurLexer->BufferEnd;
277 if (EndPos != CurLexer->BufferStart &&
278 (EndPos[-1] ==
'\n' || EndPos[-1] ==
'\r')) {
282 if (EndPos != CurLexer->BufferStart &&
283 (EndPos[-1] ==
'\n' || EndPos[-1] ==
'\r') &&
284 EndPos[-1] != EndPos[0])
296 assert(!CurTokenLexer &&
297 "Ending a file when currently in a macro!");
307 getMacroInfo(const_cast<IdentifierInfo*>(ControllingMacro))) {
308 MI->UsedForHeaderGuard =
true;
313 DefinedMacro != ControllingMacro &&
322 const StringRef ControllingMacroName = ControllingMacro->getName();
323 const StringRef DefinedMacroName = DefinedMacro->getName();
324 const size_t MaxHalfLength =
std::max(ControllingMacroName.size(),
325 DefinedMacroName.size()) / 2;
326 const unsigned ED = ControllingMacroName.edit_distance(
327 DefinedMacroName,
true, MaxHalfLength);
328 if (ED <= MaxHalfLength) {
331 diag::warn_header_guard)
334 diag::note_header_guard)
339 ControllingMacro->getName());
350 if (PragmaARCCFCodeAuditedLoc.
isValid() &&
351 !isEndOfMacro && !(CurLexer && CurLexer->Is_PragmaLexer)) {
352 Diag(PragmaARCCFCodeAuditedLoc, diag::err_pp_eof_in_arc_cf_code_audited);
361 if (PragmaAssumeNonNullLoc.
isValid() &&
362 !isEndOfMacro && !(CurLexer && CurLexer->Is_PragmaLexer)) {
363 Diag(PragmaAssumeNonNullLoc, diag::err_pp_eof_in_assume_nonnull);
371 if (!IncludeMacroStack.empty()) {
376 CodeCompletionFileLoc) {
379 CurLexer->FormTokenWithChars(Result, CurLexer->BufferEnd,
tok::eof);
382 assert(CurPTHLexer &&
"Got EOF but no current lexer set!");
383 CurPTHLexer->getEOF(Result);
387 CurPPLexer =
nullptr;
391 if (!isEndOfMacro && CurPPLexer &&
402 if (Callbacks && !isEndOfMacro && CurPPLexer)
405 bool LeavingSubmodule = CurSubmodule && CurLexer;
406 if (LeavingSubmodule) {
408 const char *EndPos = getCurLexerEndPos();
410 CurLexer->BufferPtr = EndPos;
411 CurLexer->FormTokenWithChars(Result, EndPos, tok::annot_module_end);
423 PropagateLineStartLeadingSpaceInfo(Result);
426 if (Callbacks && !isEndOfMacro && CurPPLexer) {
434 return LeavingSubmodule;
439 const char *EndPos = getCurLexerEndPos();
441 CurLexer->BufferPtr = EndPos;
442 CurLexer->FormTokenWithChars(Result, EndPos,
tok::eof);
451 if (CurLexer->getFileLoc() == CodeCompletionFileLoc)
459 assert(CurPTHLexer &&
"Got EOF but no current lexer set!");
460 CurPTHLexer->getEOF(Result);
465 CurPPLexer =
nullptr;
472 I=WarnUnusedMacroLocs.begin(),
E=WarnUnusedMacroLocs.end();
474 Diag(*
I, diag::pp_macro_not_used);
481 if (Mod->getUmbrellaHeader()) {
492 Entry !=
End && !EC; Entry.increment(EC)) {
493 using llvm::StringSwitch;
497 if (!StringSwitch<bool>(llvm::sys::path::extension(Entry->getName()))
498 .Cases(
".h",
".H",
".hh",
".hpp",
true)
509 Diag(StartLoc, diag::warn_uncovered_module_header)
510 << Mod->getFullModuleName() << RelativePath;
524 assert(CurTokenLexer && !CurPPLexer &&
525 "Ending a macro when currently in a #include file!");
527 if (!MacroExpandingLexersStack.empty() &&
528 MacroExpandingLexersStack.back().first == CurTokenLexer.get())
529 removeCachedMacroExpandedTokensOfLastLexer();
532 if (NumCachedTokenLexers == TokenLexerCacheSize)
533 CurTokenLexer.reset();
535 TokenLexerCache[NumCachedTokenLexers++] = std::move(CurTokenLexer);
545 assert(!IncludeMacroStack.empty() &&
"Ran out of stack entries to load");
549 if (NumCachedTokenLexers == TokenLexerCacheSize)
550 CurTokenLexer.reset();
552 TokenLexerCache[NumCachedTokenLexers++] = std::move(CurTokenLexer);
555 PopIncludeMacroStack();
562 assert(CurTokenLexer && !CurPPLexer &&
563 "Pasted comment can only be formed from macro");
568 bool LexerWasInPPMode =
false;
569 for (
unsigned i = 0, e = IncludeMacroStack.size(); i != e; ++i) {
570 IncludeStackInfo &ISI = *(IncludeMacroStack.end()-i-1);
571 if (ISI.ThePPLexer ==
nullptr)
continue;
579 FoundLexer = ISI.ThePPLexer;
601 if (Tok.
is(tok::eod)) {
602 assert(FoundLexer &&
"Can't get end of line without an active lexer");
608 if (LexerWasInPPMode)
return;
619 assert(!FoundLexer &&
"Lexer should return EOD before EOF in PP mode");
625 BuildingSubmoduleStack.push_back(BuildingSubmoduleInfo(
626 M, ImportLoc, CurSubmoduleState, PendingModuleMacroNames.size()));
640 auto R = Submodules.insert(std::make_pair(M, SubmoduleState()));
641 auto &
State = R.first->second;
642 bool FirstTime = R.second;
650 auto &StartingMacros = NullSubmoduleState.Macros;
654 for (
auto &Macro : StartingMacros) {
656 if (!Macro.second.getLatest() &&
657 Macro.second.getOverriddenMacros().empty())
660 MacroState MS(Macro.second.getLatest());
661 MS.setOverriddenMacros(*
this, Macro.second.getOverriddenMacros());
662 State.Macros.insert(std::make_pair(Macro.first, std::move(MS)));
667 BuildingSubmoduleStack.push_back(BuildingSubmoduleInfo(
668 M, ImportLoc, CurSubmoduleState, PendingModuleMacroNames.size()));
671 CurSubmoduleState = &
State;
678 bool Preprocessor::needModuleMacros()
const {
680 if (BuildingSubmoduleStack.empty())
691 void Preprocessor::LeaveSubmodule() {
692 auto &Info = BuildingSubmoduleStack.back();
694 Module *LeavingMod = Info.M;
697 if (!needModuleMacros() ||
703 BuildingSubmoduleStack.pop_back();
709 llvm::SmallPtrSet<const IdentifierInfo*, 8> VisitedMacros;
710 for (
unsigned I = Info.OuterPendingModuleMacroNames;
711 I != PendingModuleMacroNames.size(); ++
I) {
713 if (!VisitedMacros.insert(II).second)
716 auto MacroIt = CurSubmoduleState->Macros.find(II);
717 if (MacroIt == CurSubmoduleState->Macros.end())
719 auto &
Macro = MacroIt->second;
723 auto *OldState = Info.OuterSubmoduleState;
725 OldState = &NullSubmoduleState;
726 if (OldState && OldState != CurSubmoduleState) {
729 auto &OldMacros = OldState->Macros;
730 auto OldMacroIt = OldMacros.find(II);
731 if (OldMacroIt == OldMacros.end())
734 OldMD = OldMacroIt->second.getLatest();
739 bool ExplicitlyPublic =
false;
741 assert(MD &&
"broken macro directive chain");
749 if (Mod != LeavingMod &&
754 if (
auto *VisMD = dyn_cast<VisibilityMacroDirective>(MD)) {
757 if (VisMD->isPublic())
758 ExplicitlyPublic =
true;
759 else if (!ExplicitlyPublic)
765 Def = DefMD->getInfo();
772 if (Def || !
Macro.getOverriddenMacros().empty())
774 Macro.getOverriddenMacros(), IsNew);
779 PendingModuleMacroNames.resize(Info.OuterPendingModuleMacroNames);
788 CurSubmoduleState = Info.OuterSubmoduleState;
790 BuildingSubmoduleStack.pop_back();
SourceManager & getSourceManager() const
unsigned getInitialNumSLocEntries() const
Number of SLocEntries before lexing the file.
Lexer - This provides a simple interface that turns a text buffer into a stream of tokens...
Implements support for file system lookup, file system caching, and directory search management...
unsigned local_sloc_entry_size() const
Get the number of local SLocEntries we have.
Defines the clang::FileManager interface and associated types.
bool isHeaderInUnavailableModule(const FileEntry *Header) const
Determine whether the given header is part of a module marked 'unavailable'.
Module * getTopLevelModule()
Retrieve the top-level module for this (sub)module, which may be this module.
Defines the SourceManager interface.
Module * getCurrentModule()
Retrieves the module that we're currently building, if any.
llvm::MemoryBuffer * getBuffer(FileID FID, SourceLocation Loc, bool *Invalid=nullptr) const
Return the buffer for the specified FileID.
Defines the clang::MacroInfo and clang::MacroDirective classes.
bool resolveUses(Module *Mod, bool Complain)
Resolve all of the unresolved uses in the given module.
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
bool isInPrimaryFile() const
Return true if we're in the top-level file, not in a #include.
SourceLocation GetDefinedLocation() const
bool HandleEndOfTokenLexer(Token &Result)
Callback invoked when the current TokenLexer hits the end of its token stream.
bool hasFileInfo(const FileEntry *File) const
Module * getModuleContainingLocation(SourceLocation Loc)
Find the module that contains the specified location, either directly or indirectly.
The virtual file system interface.
One of these records is kept for each identifier that is lexed.
A directive for a defined macro or a macro imported from a module.
bool ParsingPreprocessorDirective
True when parsing #XXX; turns '\n' into a tok::eod token.
bool resolveConflicts(Module *Mod, bool Complain)
Resolve all of the unresolved conflicts in the given module.
const MacroInfo * getMacroInfo(const IdentifierInfo *II) const
const LangOptions & getLangOpts() const
Token - This structure provides full information about a lexed token.
An input iterator over the recursive contents of a virtual path, similar to llvm::sys::fs::recursive_...
Describes a module or submodule.
FileManager & getFileManager() const
SourceLocation getLocWithOffset(int Offset) const
Return a source location with the specified offset from this SourceLocation.
IntrusiveRefCntPtr< vfs::FileSystem > getVirtualFileSystem() const
HeaderSearch & getHeaderSearchInfo() const
const FileEntry * getFileEntry() const
getFileEntry - Return the FileEntry corresponding to this FileID.
detail::InMemoryDirectory::const_iterator I
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const
Forwarding function for diagnostics.
const FileEntry * getFile(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Lookup, cache, and verify the specified file (real or virtual).
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
std::string CurrentModule
The name of the current module, of which the main source file is a part.
const DirectoryEntry * getDirectory(StringRef DirName, bool CacheFailure=true)
Lookup, cache, and verify the specified directory (real or virtual).
ModuleMacro * addModuleMacro(Module *Mod, IdentifierInfo *II, MacroInfo *Macro, ArrayRef< ModuleMacro * > Overrides, bool &IsNew)
Register an exported macro for a module and identifier.
void setAnnotationValue(void *val)
bool LexingRawMode
True if in raw mode.
void makeModuleVisible(Module *M, SourceLocation Loc)
MacroArgs - An instance of this class captures information about the formal arguments specified to a ...
Defines the clang::Preprocessor interface.
const char * getBufferName(SourceLocation Loc, bool *Invalid=nullptr) const
Return the filename or buffer identifier of the buffer the location is in.
void HandleMicrosoftCommentPaste(Token &Tok)
When the macro expander pastes together a comment (/##/) in Microsoft mode, this method handles updat...
bool resolveExports(Module *Mod, bool Complain)
Resolve all of the unresolved exports in the given module.
MultipleIncludeOpt MIOpt
A state machine that detects the #ifndef-wrapping a file idiom for the multiple-include optimization...
static void computeRelativePath(FileManager &FM, const DirectoryEntry *Dir, const FileEntry *File, SmallString< 128 > &Result)
Compute the relative path that names the given file relative to the given directory.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
bool isNot(tok::TokenKind K) const
SourceLocation getIncludeLoc(FileID FID) const
Returns the include location if FID is a #include'd file otherwise it returns an invalid location...
bool HandleEndOfFile(Token &Result, bool isEndOfMacro=false)
Callback invoked when the lexer hits the end of the current file.
DirectoryLookup - This class represents one entry in the search list that specifies the search order ...
StringRef getTopLevelModuleName() const
Retrieve the name of the top-level module.
virtual SourceLocation getSourceLocation()=0
Return the source location for the next observable location.
Encapsulates changes to the "macros namespace" (the location where the macro name became active...
const char * getName() const
Encodes a location in the source.
bool isIncrementalProcessingEnabled() const
Returns true if incremental processing is enabled.
const TemplateArgument * iterator
bool isValid() const
Return true if this is a valid SourceLocation object.
void setAnnotationEndLoc(SourceLocation L)
Cached information about one file (either on disk or in the virtual file system). ...
void Lex(Token &Result)
Lex the next token for this preprocessor.
void EnterMacro(Token &Identifier, 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...
FileID getMainFileID() const
Returns the FileID of the main source file.
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 isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
DiagnosticsEngine & getDiagnostics() const
const char * getName() const
bool isMacroDefined(StringRef Id)
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
SrcMgr::CharacteristicKind getFileCharacteristic(SourceLocation Loc) const
Return the file characteristic of the specified source location, indicating whether this is a normal ...
const IdentifierInfo * GetDefinedMacro() const
If the ControllingMacro is followed by a macro definition, return the macro that was defined...
detail::InMemoryDirectory::const_iterator E
PreprocessorLexer * getCurrentFileLexer() const
Return the current file lexer being lexed from.
Encapsulates the data about a macro definition (e.g.
const IdentifierInfo * GetControllingMacroAtEndOfFile() const
Once the entire file has been lexed, if there is a controlling macro, return it.
bool isCodeCompletionEnabled() const
Determine if we are performing code completion.
Cached information about one directory (either on disk or in the virtual file system).
char __ovld __cnfn max(char x, char y)
Returns y if x < y, otherwise it returns x.
void RemoveTopOfLexerStack()
Pop the current lexer/macro exp off the top of the lexer stack.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string...
void setNumCreatedFIDsForFileID(FileID FID, unsigned NumFIDs) const
Set the number of FileIDs (files and macros) that were created during preprocessing of FID...
The translation unit is a complete translation unit.
SourceLocation GetMacroLocation() const
SourceLocation getLocForStartOfFile(FileID FID) const
Return the source location corresponding to the first byte of the specified file. ...
void setLocation(SourceLocation L)
const DirectoryEntry * getDir() const
Return the directory the file lives in.
void startToken()
Reset all flags to cleared.
const MacroDirective * getPrevious() const
Get previous definition of the macro with the same name.
bool EnterSourceFile(FileID CurFileID, const DirectoryLookup *Dir, SourceLocation Loc)
Add a source file to the top of the include stack and start lexing tokens from it instead of the curr...