mirror of https://github.com/microsoft/clang.git
Fix evaluation of `__has_include_next` during -frewrite-includes.
`__has_include_next` requires correct DirectoryLookup for being evaluated correctly. We were using Preprocessor::GetCurDirLookup() but we were calling it after the preprocessor finished its work. And in this case CurDirLookup is always nullptr which makes `__has_include_next` behave as `__has_include`. Fix by storing and using CurDirLookup when preprocessor enters a file, not when we rewrite the includes. rdar://problem/36305026 Reviewers: bkramer Reviewed By: bkramer Subscribers: jkorous-apple, cfe-commits Differential Revision: https://reviews.llvm.org/D45603 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@330041 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
bb67058712
commit
6b9cd14d39
|
@ -32,8 +32,10 @@ class InclusionRewriter : public PPCallbacks {
|
|||
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 @@ class InclusionRewriter : public PPCallbacks {
|
|||
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 @@ void InclusionRewriter::FileChanged(SourceLocation Loc,
|
|||
// 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 @@ bool InclusionRewriter::HandleHasInclude(
|
|||
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 @@ bool InclusionRewriter::HandleHasInclude(
|
|||
/// 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 @@ void InclusionRewriter::Process(FileID FileId,
|
|||
<< 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 @@ void InclusionRewriter::Process(FileID FileId,
|
|||
// 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 @@ void clang::RewriteIncludesInInput(Preprocessor &PP, raw_ostream *OS,
|
|||
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();
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
included_line9
|
|
@ -0,0 +1,3 @@
|
|||
#if __has_include_next(<rewrite-includes9.h>)
|
||||
#include_next <rewrite-includes9.h>
|
||||
#endif
|
|
@ -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 @@ A(1,2)
|
|||
#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 @@ A(1,2)
|
|||
// 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(<rewrite-includes8.h>)*/{{$}}
|
||||
// CHECK-NEXT: {{^}}#if (0)/*__has_include_next(<rewrite-includes8.h>)*/{{$}}
|
||||
// CHECK-NEXT: {{^}}#elif (0)/*__has_include(<rewrite-includes8.hfail>)*/{{$}}
|
||||
// CHECK-NEXT: {{^}}# 3 "{{.*[/\\]Inputs(/|\\\\)}}rewrite-includes8.h"{{$}}
|
||||
// CHECK-NEXT: {{^}}#endif{{$}}
|
||||
|
@ -118,6 +119,22 @@ A(1,2)
|
|||
// 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(<rewrite-includes9.h>)*/{{$}}
|
||||
// CHECK-NEXT: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}}
|
||||
// CHECK-NEXT: {{^}}#include_next <rewrite-includes9.h>{{$}}
|
||||
// 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 @@ A(1,2)
|
|||
// 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(<rewrite-includes8.h>)*/{{$}}
|
||||
// CHECKNL-NEXT: {{^}}#if (0)/*__has_include_next(<rewrite-includes8.h>)*/{{$}}
|
||||
// CHECKNL-NEXT: {{^}}#elif (0)/*__has_include(<rewrite-includes8.hfail>)*/{{$}}
|
||||
// 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(<rewrite-includes9.h>)*/{{$}}
|
||||
// CHECKNL-NEXT: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}}
|
||||
// CHECKNL-NEXT: {{^}}#include_next <rewrite-includes9.h>{{$}}
|
||||
// CHECKNL-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}}
|
||||
// CHECKNL-NEXT: {{^}}included_line9{{$}}
|
||||
// CHECKNL-NEXT: {{^}}#endif{{$}}
|
||||
// CHECKNL-NEXT: {{^}}// ENDCOMPARE{{$}}
|
||||
|
|
Loading…
Reference in New Issue