Index: lib/Frontend/Rewrite/InclusionRewriter.cpp =================================================================== --- lib/Frontend/Rewrite/InclusionRewriter.cpp +++ lib/Frontend/Rewrite/InclusionRewriter.cpp @@ -79,8 +79,9 @@ void CommentOutDirective(Lexer &DirectivesLex, const Token &StartToken, const MemoryBuffer &FromFile, StringRef EOL, unsigned &NextToWrite, int &Lines); + enum HasIncludeKind { HasIncludeNormal, HasIncludeNext }; bool HandleHasInclude(FileID FileId, Lexer &RawLex, - const DirectoryLookup *Lookup, Token &Tok, + HasIncludeKind HasIncludeVariant, Token &Tok, bool &FileExists); const IncludedFile *FindIncludeAtLocation(SourceLocation Loc) const; const Module *FindModuleAtLocation(SourceLocation Loc) const; @@ -327,7 +328,7 @@ // Expand __has_include and __has_include_next if possible. If there's no // definitive answer return false. bool InclusionRewriter::HandleHasInclude( - FileID FileId, Lexer &RawLex, const DirectoryLookup *Lookup, Token &Tok, + FileID FileId, Lexer &RawLex, HasIncludeKind HasIncludeVariant, Token &Tok, bool &FileExists) { // Lex the opening paren. RawLex.LexFromRawLexer(Tok); @@ -384,14 +385,25 @@ // Now ask HeaderInfo if it knows about the header. // FIXME: Subframeworks aren't handled here. Do we care? bool isAngled = PP.GetIncludeFilenameSpelling(Tok.getLocation(), Filename); - const DirectoryLookup *CurDir; const FileEntry *FileEnt = PP.getSourceManager().getFileEntryForID(FileId); SmallVector, 1> Includers; Includers.push_back(std::make_pair(FileEnt, FileEnt->getDir())); + const DirectoryLookup *Lookup = nullptr; + + if (HasIncludeVariant == HasIncludeNext) { + // Find lookup for file and move past it. + PP.getHeaderSearchInfo().LookupFile(Filename, SourceLocation(), isAngled, + nullptr, Lookup, Includers, nullptr, + nullptr, nullptr, nullptr, false); + if (Lookup) + Lookup++; + } + + const DirectoryLookup *CurDir; // FIXME: Why don't we call PP.LookupFile here? const FileEntry *File = PP.getHeaderSearchInfo().LookupFile( - Filename, SourceLocation(), isAngled, nullptr, CurDir, Includers, nullptr, + Filename, SourceLocation(), isAngled, Lookup, CurDir, Includers, nullptr, nullptr, nullptr, nullptr, false); FileExists = File != nullptr; @@ -505,17 +517,13 @@ // Rewrite __has_include(x) if (RawToken.getIdentifierInfo()->isStr("__has_include")) { - if (!HandleHasInclude(FileId, RawLex, nullptr, RawToken, + if (!HandleHasInclude(FileId, RawLex, HasIncludeNormal, RawToken, HasFile)) continue; // Rewrite __has_include_next(x) } else if (RawToken.getIdentifierInfo()->isStr( "__has_include_next")) { - const DirectoryLookup *Lookup = PP.GetCurDirLookup(); - if (Lookup) - ++Lookup; - - if (!HandleHasInclude(FileId, RawLex, Lookup, RawToken, + if (!HandleHasInclude(FileId, RawLex, HasIncludeNext, RawToken, HasFile)) continue; } else { Index: test/Frontend/rewrite-includes.c =================================================================== --- test/Frontend/rewrite-includes.c +++ test/Frontend/rewrite-includes.c @@ -109,7 +109,7 @@ // CHECK-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}} // CHECK-NEXT: {{^}}# 22 "{{.*}}rewrite-includes.c"{{$}} // CHECK-NEXT: {{^}}# 1 "{{.*[/\\]Inputs(/|\\\\)}}rewrite-includes8.h" 1{{$}} -// CHECK-NEXT: {{^}}#if (1)/*__has_include_next()*/{{$}} +// CHECK-NEXT: {{^}}#if (0)/*__has_include_next()*/{{$}} // CHECK-NEXT: {{^}}#elif (0)/*__has_include()*/{{$}} // CHECK-NEXT: {{^}}# 3 "{{.*[/\\]Inputs(/|\\\\)}}rewrite-includes8.h"{{$}} // CHECK-NEXT: {{^}}#endif{{$}} @@ -176,7 +176,7 @@ // CHECKNL-NEXT: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}} // CHECKNL-NEXT: {{^}}#include "rewrite-includes8.h"{{$}} // CHECKNL-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}} -// CHECKNL-NEXT: {{^}}#if (1)/*__has_include_next()*/{{$}} +// CHECKNL-NEXT: {{^}}#if (0)/*__has_include_next()*/{{$}} // CHECKNL-NEXT: {{^}}#elif (0)/*__has_include()*/{{$}} // CHECKNL-NEXT: {{^}}#endif{{$}} // CHECKNL-NEXT: {{^}}#if !(1)/*__has_include("rewrite-includes8.h")*/{{$}}