Index: lib/Frontend/Rewrite/InclusionRewriter.cpp =================================================================== --- lib/Frontend/Rewrite/InclusionRewriter.cpp +++ lib/Frontend/Rewrite/InclusionRewriter.cpp @@ -32,8 +32,10 @@ struct IncludedFile { FileID Id; SrcMgr::CharacteristicKind FileType; - IncludedFile(FileID Id, SrcMgr::CharacteristicKind FileType) - : Id(Id), FileType(FileType) {} + const DirectoryLookup *DirLookup; + IncludedFile(FileID Id, SrcMgr::CharacteristicKind FileType, + const DirectoryLookup *DirLookup) + : Id(Id), FileType(FileType), DirLookup(DirLookup) {} }; Preprocessor &PP; ///< Used to find inclusion directives. SourceManager &SM; ///< Used to read and manage source files. @@ -54,7 +56,8 @@ public: InclusionRewriter(Preprocessor &PP, raw_ostream &OS, bool ShowLineMarkers, bool UseLineDirectives); - void Process(FileID FileId, SrcMgr::CharacteristicKind FileType); + void Process(FileID FileId, SrcMgr::CharacteristicKind FileType, + const DirectoryLookup *DirLookup); void setPredefinesBuffer(const llvm::MemoryBuffer *Buf) { PredefinesBuffer = Buf; } @@ -156,8 +159,9 @@ // we didn't reach this file (eg: the main file) via an inclusion directive return; FileID Id = FullSourceLoc(Loc, SM).getFileID(); - auto P = FileIncludes.insert(std::make_pair( - LastInclusionLocation.getRawEncoding(), IncludedFile(Id, NewFileType))); + auto P = FileIncludes.insert( + std::make_pair(LastInclusionLocation.getRawEncoding(), + IncludedFile(Id, NewFileType, PP.GetCurDirLookup()))); (void)P; assert(P.second && "Unexpected revisitation of the same include directive"); LastInclusionLocation = SourceLocation(); @@ -408,7 +412,7 @@ Includers.push_back(std::make_pair(FileEnt, FileEnt->getDir())); // 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, nullptr); FileExists = File != nullptr; @@ -418,7 +422,8 @@ /// Use a raw lexer to analyze \p FileId, incrementally copying parts of it /// and including content of included files recursively. void InclusionRewriter::Process(FileID FileId, - SrcMgr::CharacteristicKind FileType) { + SrcMgr::CharacteristicKind FileType, + const DirectoryLookup *DirLookup) { bool Invalid; const MemoryBuffer &FromFile = *SM.getBuffer(FileId, &Invalid); assert(!Invalid && "Attempting to process invalid inclusion"); @@ -475,7 +480,7 @@ << Mod->getFullModuleName(true) << "\n"; // Include and recursively process the file. - Process(Inc->Id, Inc->FileType); + Process(Inc->Id, Inc->FileType, Inc->DirLookup); if (Mod) OS << "#pragma clang module end /*" @@ -532,11 +537,10 @@ // Rewrite __has_include_next(x) } else if (RawToken.getIdentifierInfo()->isStr( "__has_include_next")) { - const DirectoryLookup *Lookup = PP.GetCurDirLookup(); - if (Lookup) - ++Lookup; + if (DirLookup) + ++DirLookup; - if (!HandleHasInclude(FileId, RawLex, Lookup, RawToken, + if (!HandleHasInclude(FileId, RawLex, DirLookup, RawToken, HasFile)) continue; } else { @@ -621,7 +625,7 @@ Rewrite->handleModuleBegin(Tok); } while (Tok.isNot(tok::eof)); Rewrite->setPredefinesBuffer(SM.getBuffer(PP.getPredefinesFileID())); - Rewrite->Process(PP.getPredefinesFileID(), SrcMgr::C_User); - Rewrite->Process(SM.getMainFileID(), SrcMgr::C_User); + Rewrite->Process(PP.getPredefinesFileID(), SrcMgr::C_User, nullptr); + Rewrite->Process(SM.getMainFileID(), SrcMgr::C_User, nullptr); OS->flush(); } Index: test/Frontend/Inputs/NextIncludes/rewrite-includes9.h =================================================================== --- test/Frontend/Inputs/NextIncludes/rewrite-includes9.h +++ test/Frontend/Inputs/NextIncludes/rewrite-includes9.h @@ -0,0 +1 @@ +included_line9 Index: test/Frontend/Inputs/rewrite-includes9.h =================================================================== --- test/Frontend/Inputs/rewrite-includes9.h +++ test/Frontend/Inputs/rewrite-includes9.h @@ -0,0 +1,3 @@ +#if __has_include_next() +#include_next +#endif Index: test/Frontend/rewrite-includes.c =================================================================== --- test/Frontend/rewrite-includes.c +++ test/Frontend/rewrite-includes.c @@ -1,5 +1,5 @@ -// RUN: not %clang_cc1 -verify -E -frewrite-includes -DFIRST -I %S/Inputs %s -o - | FileCheck -strict-whitespace %s -// RUN: not %clang_cc1 -verify -E -frewrite-includes -P -DFIRST -I %S/Inputs %s -o - | FileCheck -check-prefix=CHECKNL -strict-whitespace %s +// RUN: not %clang_cc1 -verify -E -frewrite-includes -DFIRST -I %S/Inputs -I %S/Inputs/NextIncludes %s -o - | FileCheck -strict-whitespace %s +// RUN: not %clang_cc1 -verify -E -frewrite-includes -P -DFIRST -I %S/Inputs -I %S/Inputs/NextIncludes %s -o - | FileCheck -check-prefix=CHECKNL -strict-whitespace %s // STARTCOMPARE #define A(a,b) a ## b A(1,2) @@ -20,6 +20,7 @@ #include "rewrite-includes7.h" #include "rewrite-includes7.h" #include "rewrite-includes8.h" +#include "rewrite-includes9.h" // ENDCOMPARE // CHECK: {{^}}# 1 "{{.*}}rewrite-includes.c"{{$}} // CHECK: {{^}}// STARTCOMPARE{{$}} @@ -109,7 +110,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{{$}} @@ -118,6 +119,22 @@ // CHECK-NEXT: {{^}}#endif{{$}} // CHECK-NEXT: {{^}}# 6 "{{.*[/\\]Inputs(/|\\\\)}}rewrite-includes8.h"{{$}} // CHECK-NEXT: {{^}}# 23 "{{.*}}rewrite-includes.c" 2{{$}} +// CHECK-NEXT: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}} +// CHECK-NEXT: {{^}}#include "rewrite-includes9.h"{{$}} +// CHECK-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}} +// CHECK-NEXT: {{^}}# 23 "{{.*}}rewrite-includes.c"{{$}} +// CHECK-NEXT: {{^}}# 1 "{{.*[/\\]Inputs(/|\\\\)}}rewrite-includes9.h" 1{{$}} +// CHECK-NEXT: {{^}}#if (1)/*__has_include_next()*/{{$}} +// CHECK-NEXT: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}} +// CHECK-NEXT: {{^}}#include_next {{$}} +// CHECK-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}} +// CHECK-NEXT: {{^}}# 2 "{{.*[/\\]Inputs(/|\\\\)}}rewrite-includes9.h"{{$}} +// CHECK-NEXT: {{^}}# 1 "{{.*[/\\]Inputs(/|\\\\)NextIncludes(/|\\\\)}}rewrite-includes9.h" 1{{$}} +// CHECK-NEXT: {{^}}included_line9{{$}} +// CHECK-NEXT: {{^}}# 3 "{{.*[/\\]Inputs(/|\\\\)}}rewrite-includes9.h" 2{{$}} +// CHECK-NEXT: {{^}}#endif{{$}} +// CHECK-NEXT: {{^}}# 4 "{{.*[/\\]Inputs(/|\\\\)}}rewrite-includes9.h"{{$}} +// CHECK-NEXT: {{^}}# 24 "{{.*}}rewrite-includes.c" 2{{$}} // CHECK-NEXT: {{^}}// ENDCOMPARE{{$}} // CHECKNL: {{^}}// STARTCOMPARE{{$}} @@ -176,9 +193,18 @@ // 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")*/{{$}} // CHECKNL-NEXT: {{^}}#endif{{$}} +// CHECKNL-NEXT: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}} +// CHECKNL-NEXT: {{^}}#include "rewrite-includes9.h"{{$}} +// CHECKNL-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}} +// CHECKNL-NEXT: {{^}}#if (1)/*__has_include_next()*/{{$}} +// CHECKNL-NEXT: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}} +// CHECKNL-NEXT: {{^}}#include_next {{$}} +// CHECKNL-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}} +// CHECKNL-NEXT: {{^}}included_line9{{$}} +// CHECKNL-NEXT: {{^}}#endif{{$}} // CHECKNL-NEXT: {{^}}// ENDCOMPARE{{$}}