Index: clang/include/clang/Basic/FileEntry.h =================================================================== --- clang/include/clang/Basic/FileEntry.h +++ clang/include/clang/Basic/FileEntry.h @@ -359,6 +359,9 @@ const DirectoryEntry *Dir = nullptr; // Directory file lives in. llvm::sys::fs::UniqueID UniqueID; unsigned UID = 0; // A unique (small) ID for the file. + // Bitfieldiness vvvvv, mutabley? + // Maybe the including machinery should use a map?? + mutable unsigned Includedness = 0; // FIXME:DOCUMENT bool IsNamedPipe = false; /// The open file, if it is owned by the \p FileEntry. @@ -393,6 +396,12 @@ /// the native FileManager methods). bool isNamedPipe() const { return IsNamedPipe; } + bool isEntered() const { return Includedness != 0; } + void EnterOrLeave(bool Enter) const { + assert(Enter || Includedness); + Includedness += Enter ? +1 : -1; + } + void closeFile() const; }; Index: clang/lib/Lex/PPDirectives.cpp =================================================================== --- clang/lib/Lex/PPDirectives.cpp +++ clang/lib/Lex/PPDirectives.cpp @@ -2329,6 +2329,9 @@ bool IsFirstIncludeOfFile = false; + if (Action == Enter && File && File->getFileEntry().isEntered()) + Diag(FilenameTok.getLocation(), diag::warn_include_cycle); + // Ask HeaderInfo if we should enter this #include file. If not, #including // this file will have no effect. if (Action == Enter && File && Index: clang/lib/Lex/PPLexerChange.cpp =================================================================== --- clang/lib/Lex/PPLexerChange.cpp +++ clang/lib/Lex/PPLexerChange.cpp @@ -103,6 +103,10 @@ } } + if (TheLexer->getPP()) + if (auto *FE = SourceMgr.getFileEntryForID(FID)) + FE->EnterOrLeave(true); + EnterSourceFileWithLexer(TheLexer, CurDir); return false; } @@ -432,6 +436,10 @@ // lexing the #includer file. if (!IncludeMacroStack.empty()) { + if (CurPPLexer) + if (auto *FE = SourceMgr.getFileEntryForID(CurPPLexer->getFileID())) + FE->EnterOrLeave(false); + // If we lexed the code-completion file, act as if we reached EOF. if (isCodeCompletionEnabled() && CurPPLexer && SourceMgr.getLocForStartOfFile(CurPPLexer->getFileID()) ==