21 #include "llvm/ADT/StringSwitch.h"
22 #include "llvm/Support/FileSystem.h"
23 #include "llvm/Support/MemoryBuffer.h"
24 #include "llvm/Support/Path.h"
25 using namespace clang;
37 return IncludeMacroStack.empty();
40 assert(IsFileLexer(IncludeMacroStack[0]) &&
41 "Top level include stack isn't our primary lexer?");
42 for (
unsigned i = 1, e = IncludeMacroStack.size(); i != e; ++i)
43 if (IsFileLexer(IncludeMacroStack[i]))
56 for (
unsigned i = IncludeMacroStack.size(); i != 0; --i) {
57 const IncludeStackInfo& ISI = IncludeMacroStack[i-1];
59 return ISI.ThePPLexer;
73 assert(!CurTokenLexer &&
"Cannot #include a file inside a macro!");
74 ++NumEnteredSourceFiles;
76 if (MaxIncludeStackDepth < IncludeMacroStack.size())
77 MaxIncludeStackDepth = IncludeMacroStack.size();
80 if (
PTHLexer *PL = PTH->CreateLexer(FID)) {
81 EnterSourceFileWithPTH(PL, CurDir);
88 const llvm::MemoryBuffer *InputFile =
92 Diag(Loc, diag::err_pp_error_opening_file)
104 EnterSourceFileWithLexer(
new Lexer(FID, InputFile, *
this), CurDir);
110 void Preprocessor::EnterSourceFileWithLexer(
Lexer *TheLexer,
114 if (CurPPLexer || CurTokenLexer)
115 PushIncludeMacroStack();
117 CurLexer.reset(TheLexer);
118 CurPPLexer = TheLexer;
119 CurDirLookup = CurDir;
120 CurSubmodule =
nullptr;
121 if (CurLexerKind != CLK_LexAfterModuleImport)
122 CurLexerKind = CLK_Lexer;
125 if (Callbacks && !CurLexer->Is_PragmaLexer) {
129 Callbacks->FileChanged(CurLexer->getFileLoc(),
136 void Preprocessor::EnterSourceFileWithPTH(
PTHLexer *PL,
139 if (CurPPLexer || CurTokenLexer)
140 PushIncludeMacroStack();
142 CurDirLookup = CurDir;
143 CurPTHLexer.reset(PL);
144 CurPPLexer = CurPTHLexer.get();
145 CurSubmodule =
nullptr;
146 if (CurLexerKind != CLK_LexAfterModuleImport)
147 CurLexerKind = CLK_PTHLexer;
163 std::unique_ptr<TokenLexer> TokLexer;
164 if (NumCachedTokenLexers == 0) {
165 TokLexer = llvm::make_unique<TokenLexer>(Tok, ILEnd, Macro, Args, *
this);
167 TokLexer = std::move(TokenLexerCache[--NumCachedTokenLexers]);
168 TokLexer->Init(Tok, ILEnd, Macro, Args);
171 PushIncludeMacroStack();
172 CurDirLookup =
nullptr;
173 CurTokenLexer = std::move(TokLexer);
174 if (CurLexerKind != CLK_LexAfterModuleImport)
175 CurLexerKind = CLK_TokenLexer;
191 bool DisableMacroExpansion,
193 if (CurLexerKind == CLK_CachingLexer) {
198 Toks, Toks + NumToks);
206 ExitCachingLexMode();
208 EnterCachingLexMode();
213 std::unique_ptr<TokenLexer> TokLexer;
214 if (NumCachedTokenLexers == 0) {
215 TokLexer = llvm::make_unique<TokenLexer>(
216 Toks, NumToks, DisableMacroExpansion, OwnsTokens, *
this);
218 TokLexer = std::move(TokenLexerCache[--NumCachedTokenLexers]);
219 TokLexer->Init(Toks, NumToks, DisableMacroExpansion, OwnsTokens);
223 PushIncludeMacroStack();
224 CurDirLookup =
nullptr;
225 CurTokenLexer = std::move(TokLexer);
226 if (CurLexerKind != CLK_LexAfterModuleImport)
227 CurLexerKind = CLK_TokenLexer;
238 StringRef Path = FilePath;
239 while (!Path.empty()) {
242 Result = FilePath.substr(Path.size());
243 llvm::sys::path::append(Result,
244 llvm::sys::path::filename(File->
getName()));
249 Path = llvm::sys::path::parent_path(Path);
255 void Preprocessor::PropagateLineStartLeadingSpaceInfo(
Token &Result) {
257 CurTokenLexer->PropagateLineStartLeadingSpaceInfo(Result);
261 CurLexer->PropagateLineStartLeadingSpaceInfo(Result);
274 const char *Preprocessor::getCurLexerEndPos() {
275 const char *EndPos = CurLexer->BufferEnd;
276 if (EndPos != CurLexer->BufferStart &&
277 (EndPos[-1] ==
'\n' || EndPos[-1] ==
'\r')) {
281 if (EndPos != CurLexer->BufferStart &&
282 (EndPos[-1] ==
'\n' || EndPos[-1] ==
'\r') &&
283 EndPos[-1] != EndPos[0])
295 assert(!CurTokenLexer &&
296 "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;
471 for (WarnUnusedMacroLocsTy::iterator
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");
569 bool LexerWasInPPMode =
false;
570 for (
unsigned i = 0, e = IncludeMacroStack.size(); i != e; ++i) {
571 IncludeStackInfo &ISI = *(IncludeMacroStack.end()-i-1);
572 if (ISI.ThePPLexer ==
nullptr)
continue;
580 FoundLexer = ISI.ThePPLexer;
602 if (Tok.
is(tok::eod)) {
603 assert(FoundLexer &&
"Can't get end of line without an active lexer");
609 if (LexerWasInPPMode)
return;
620 assert(!FoundLexer &&
"Lexer should return EOD before EOF in PP mode");
626 BuildingSubmoduleStack.push_back(
627 BuildingSubmoduleInfo(M, ImportLoc, CurSubmoduleState));
641 auto R = Submodules.insert(std::make_pair(M, SubmoduleState()));
642 auto &
State = R.first->second;
643 bool FirstTime = R.second;
651 auto &StartingMacros = NullSubmoduleState.Macros;
655 for (
auto &Macro : StartingMacros) {
657 if (!Macro.second.getLatest() &&
658 Macro.second.getOverriddenMacros().empty())
661 MacroState MS(Macro.second.getLatest());
662 MS.setOverriddenMacros(*
this, Macro.second.getOverriddenMacros());
663 State.Macros.insert(std::make_pair(Macro.first, std::move(MS)));
668 BuildingSubmoduleStack.push_back(
669 BuildingSubmoduleInfo(M, ImportLoc, CurSubmoduleState));
672 CurSubmoduleState = &
State;
679 void Preprocessor::LeaveSubmodule() {
680 auto &Info = BuildingSubmoduleStack.back();
682 Module *LeavingMod = Info.M;
686 for (
auto &Macro : CurSubmoduleState->Macros) {
694 auto &PredefMacros = NullSubmoduleState.Macros;
695 auto PredefMacroIt = PredefMacros.find(Macro.first);
696 if (PredefMacroIt == PredefMacros.end())
699 OldMD = PredefMacroIt->second.getLatest();
704 bool ExplicitlyPublic =
false;
705 for (
auto *MD = Macro.second.getLatest(); MD != OldMD;
707 assert(MD &&
"broken macro directive chain");
714 if (Mod != LeavingMod)
718 if (
auto *VisMD = dyn_cast<VisibilityMacroDirective>(MD)) {
721 if (VisMD->isPublic())
722 ExplicitlyPublic =
true;
723 else if (!ExplicitlyPublic)
729 Def = DefMD->getInfo();
736 if (Def || !Macro.second.getOverriddenMacros().empty())
738 Macro.second.getOverriddenMacros(), IsNew);
751 CurSubmoduleState = Info.OuterSubmoduleState;
753 BuildingSubmoduleStack.pop_back();
SourceManager & getSourceManager() const
unsigned getInitialNumSLocEntries() const
Number of SLocEntries before lexing the file.
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'.
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.
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
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
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const
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.
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)
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)
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.
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. The SourceManager can decode this to get at the full include stack...
bool isIncrementalProcessingEnabled() const
Returns true if incremental processing is enabled.
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 EnterTokenStream(const Token *Toks, unsigned NumToks, bool DisableMacroExpansion, bool OwnsTokens)
Add a "macro" context to the top of the include stack, which will cause the lexer to start returning ...
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
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...
PreprocessorLexer * getCurrentFileLexer() const
Return the current file lexer being lexed from.
Encapsulates the data about a macro definition (e.g. its tokens).
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).
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...