forked from OSchip/llvm-project
Preprocessor: Suppress -Wnonportable-include-path for header maps
If a file search involves a header map, suppress -Wnonportable-include-path. It's firing lots of false positives for framework authors internally, and it's not trivial to fix. Consider a framework called "Foo" with a main (installed) framework header "Foo/Foo.h". It's atypical for "Foo.h" to actually live inside a directory called "Foo" in the source repository. Instead, the build system generates a header map while building the framework. If Foo.h lives at the top-level of the source repository (common), and the git repo is called ssh://some.url/foo.git, then the header map will have something like: Foo/Foo.h -> /Users/myname/code/foo/Foo.h where "/Users/myname/code/foo" is the clone of ssh://some.url/foo.git. After #import <Foo/Foo.h>, the current implementation of -Wnonportable-include-path will falsely assume that Foo.h was found in a nonportable way, because of the name of the git clone (.../foo/Foo.h). However, that directory name was not involved in the header search at all. This commit adds an extra parameter to Preprocessor::LookupFile and HeaderSearch::LookupFile to track if the search used a header map, making it easy to suppress the warning. Longer term, once we find a way to avoid the false positive, we should turn the warning back on. rdar://problem/28863903 llvm-svn: 301592
This commit is contained in:
parent
d2d007707a
commit
cfc1f6a6ee
|
@ -375,13 +375,16 @@ public:
|
|||
/// \param SuggestedModule If non-null, and the file found is semantically
|
||||
/// part of a known module, this will be set to the module that should
|
||||
/// be imported instead of preprocessing/parsing the file found.
|
||||
///
|
||||
/// \param IsMapped If non-null, and the search involved header maps, set to
|
||||
/// true.
|
||||
const FileEntry *LookupFile(
|
||||
StringRef Filename, SourceLocation IncludeLoc, bool isAngled,
|
||||
const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir,
|
||||
ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>> Includers,
|
||||
SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
|
||||
Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule,
|
||||
bool SkipCache = false, bool BuildSystemModule = false);
|
||||
bool *IsMapped, bool SkipCache = false, bool BuildSystemModule = false);
|
||||
|
||||
/// \brief Look up a subframework for the specified \#include file.
|
||||
///
|
||||
|
|
|
@ -1686,7 +1686,7 @@ public:
|
|||
SmallVectorImpl<char> *SearchPath,
|
||||
SmallVectorImpl<char> *RelativePath,
|
||||
ModuleMap::KnownHeader *SuggestedModule,
|
||||
bool SkipCache = false);
|
||||
bool *IsMapped, bool SkipCache = false);
|
||||
|
||||
/// \brief Get the DirectoryLookup structure used to find the current
|
||||
/// FileEntry, if CurLexer is non-null and if applicable.
|
||||
|
|
|
@ -858,7 +858,8 @@ bool CompilerInstance::InitializeSourceManager(
|
|||
/*SearchPath=*/nullptr,
|
||||
/*RelativePath=*/nullptr,
|
||||
/*RequestingModule=*/nullptr,
|
||||
/*SuggestedModule=*/nullptr, /*SkipCache=*/true);
|
||||
/*SuggestedModule=*/nullptr, /*IsMapped=*/nullptr,
|
||||
/*SkipCache=*/true);
|
||||
// Also add the header to /showIncludes output.
|
||||
if (File)
|
||||
DepOpts.ShowIncludesPretendHeader = File->getName();
|
||||
|
|
|
@ -392,7 +392,7 @@ bool InclusionRewriter::HandleHasInclude(
|
|||
// FIXME: Why don't we call PP.LookupFile here?
|
||||
const FileEntry *File = PP.getHeaderSearchInfo().LookupFile(
|
||||
Filename, SourceLocation(), isAngled, nullptr, CurDir, Includers, nullptr,
|
||||
nullptr, nullptr, nullptr, false);
|
||||
nullptr, nullptr, nullptr, nullptr);
|
||||
|
||||
FileExists = File != nullptr;
|
||||
return true;
|
||||
|
|
|
@ -400,7 +400,7 @@ static bool ParseDirective(StringRef S, ExpectedData *ED, SourceManager &SM,
|
|||
const DirectoryLookup *CurDir;
|
||||
const FileEntry *FE =
|
||||
PP->LookupFile(Pos, Filename, false, nullptr, nullptr, CurDir,
|
||||
nullptr, nullptr, nullptr);
|
||||
nullptr, nullptr, nullptr, nullptr);
|
||||
if (!FE) {
|
||||
Diags.Report(Pos.getLocWithOffset(PH.C-PH.Begin),
|
||||
diag::err_verify_missing_file) << Filename << KindStr;
|
||||
|
|
|
@ -624,7 +624,10 @@ const FileEntry *HeaderSearch::LookupFile(
|
|||
ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>> Includers,
|
||||
SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
|
||||
Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule,
|
||||
bool SkipCache, bool BuildSystemModule) {
|
||||
bool *IsMapped, bool SkipCache, bool BuildSystemModule) {
|
||||
if (IsMapped)
|
||||
*IsMapped = false;
|
||||
|
||||
if (SuggestedModule)
|
||||
*SuggestedModule = ModuleMap::KnownHeader();
|
||||
|
||||
|
@ -754,8 +757,11 @@ const FileEntry *HeaderSearch::LookupFile(
|
|||
if (!SkipCache && CacheLookup.StartIdx == i+1) {
|
||||
// Skip querying potentially lots of directories for this lookup.
|
||||
i = CacheLookup.HitIdx;
|
||||
if (CacheLookup.MappedName)
|
||||
if (CacheLookup.MappedName) {
|
||||
Filename = CacheLookup.MappedName;
|
||||
if (IsMapped)
|
||||
*IsMapped = true;
|
||||
}
|
||||
} else {
|
||||
// Otherwise, this is the first query, or the previous query didn't match
|
||||
// our search start. We will fill in our found location below, so prime the
|
||||
|
@ -776,6 +782,8 @@ const FileEntry *HeaderSearch::LookupFile(
|
|||
if (HasBeenMapped) {
|
||||
CacheLookup.MappedName =
|
||||
copyString(Filename, LookupFileCache.getAllocator());
|
||||
if (IsMapped)
|
||||
*IsMapped = true;
|
||||
}
|
||||
if (!FE) continue;
|
||||
|
||||
|
@ -839,7 +847,7 @@ const FileEntry *HeaderSearch::LookupFile(
|
|||
const FileEntry *FE =
|
||||
LookupFile(ScratchFilename, IncludeLoc, /*isAngled=*/true, FromDir,
|
||||
CurDir, Includers.front(), SearchPath, RelativePath,
|
||||
RequestingModule, SuggestedModule);
|
||||
RequestingModule, SuggestedModule, IsMapped);
|
||||
|
||||
if (checkMSVCHeaderSearch(Diags, MSFE, FE, IncludeLoc)) {
|
||||
if (SuggestedModule)
|
||||
|
|
|
@ -752,16 +752,11 @@ Preprocessor::getModuleHeaderToIncludeForDiagnostics(SourceLocation IncLoc,
|
|||
}
|
||||
|
||||
const FileEntry *Preprocessor::LookupFile(
|
||||
SourceLocation FilenameLoc,
|
||||
StringRef Filename,
|
||||
bool isAngled,
|
||||
const DirectoryLookup *FromDir,
|
||||
const FileEntry *FromFile,
|
||||
const DirectoryLookup *&CurDir,
|
||||
SmallVectorImpl<char> *SearchPath,
|
||||
SourceLocation FilenameLoc, StringRef Filename, bool isAngled,
|
||||
const DirectoryLookup *FromDir, const FileEntry *FromFile,
|
||||
const DirectoryLookup *&CurDir, SmallVectorImpl<char> *SearchPath,
|
||||
SmallVectorImpl<char> *RelativePath,
|
||||
ModuleMap::KnownHeader *SuggestedModule,
|
||||
bool SkipCache) {
|
||||
ModuleMap::KnownHeader *SuggestedModule, bool *IsMapped, bool SkipCache) {
|
||||
Module *RequestingModule = getModuleForLocation(FilenameLoc);
|
||||
bool RequestingModuleIsModuleInterface = !SourceMgr.isInMainFile(FilenameLoc);
|
||||
|
||||
|
@ -819,7 +814,7 @@ const FileEntry *Preprocessor::LookupFile(
|
|||
while (const FileEntry *FE = HeaderInfo.LookupFile(
|
||||
Filename, FilenameLoc, isAngled, TmpFromDir, TmpCurDir,
|
||||
Includers, SearchPath, RelativePath, RequestingModule,
|
||||
SuggestedModule, SkipCache)) {
|
||||
SuggestedModule, /*IsMapped=*/nullptr, SkipCache)) {
|
||||
// Keep looking as if this file did a #include_next.
|
||||
TmpFromDir = TmpCurDir;
|
||||
++TmpFromDir;
|
||||
|
@ -835,7 +830,7 @@ const FileEntry *Preprocessor::LookupFile(
|
|||
// Do a standard file entry lookup.
|
||||
const FileEntry *FE = HeaderInfo.LookupFile(
|
||||
Filename, FilenameLoc, isAngled, FromDir, CurDir, Includers, SearchPath,
|
||||
RelativePath, RequestingModule, SuggestedModule, SkipCache,
|
||||
RelativePath, RequestingModule, SuggestedModule, IsMapped, SkipCache,
|
||||
BuildSystemModule);
|
||||
if (FE) {
|
||||
if (SuggestedModule && !LangOpts.AsmPreprocessor)
|
||||
|
@ -1783,6 +1778,7 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
|
|||
}
|
||||
|
||||
// Search include directories.
|
||||
bool IsMapped = false;
|
||||
const DirectoryLookup *CurDir;
|
||||
SmallString<1024> SearchPath;
|
||||
SmallString<1024> RelativePath;
|
||||
|
@ -1801,7 +1797,7 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
|
|||
FilenameLoc, LangOpts.MSVCCompat ? NormalizedPath.c_str() : Filename,
|
||||
isAngled, LookupFrom, LookupFromFile, CurDir,
|
||||
Callbacks ? &SearchPath : nullptr, Callbacks ? &RelativePath : nullptr,
|
||||
&SuggestedModule);
|
||||
&SuggestedModule, &IsMapped);
|
||||
|
||||
if (!File) {
|
||||
if (Callbacks) {
|
||||
|
@ -1818,7 +1814,7 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
|
|||
FilenameLoc,
|
||||
LangOpts.MSVCCompat ? NormalizedPath.c_str() : Filename, isAngled,
|
||||
LookupFrom, LookupFromFile, CurDir, nullptr, nullptr,
|
||||
&SuggestedModule, /*SkipCache*/ true);
|
||||
&SuggestedModule, &IsMapped, /*SkipCache*/ true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1833,8 +1829,7 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
|
|||
LangOpts.MSVCCompat ? NormalizedPath.c_str() : Filename, false,
|
||||
LookupFrom, LookupFromFile, CurDir,
|
||||
Callbacks ? &SearchPath : nullptr,
|
||||
Callbacks ? &RelativePath : nullptr,
|
||||
&SuggestedModule);
|
||||
Callbacks ? &RelativePath : nullptr, &SuggestedModule, &IsMapped);
|
||||
if (File) {
|
||||
SourceRange Range(FilenameTok.getLocation(), CharEnd);
|
||||
Diag(FilenameTok, diag::err_pp_file_not_found_not_fatal) <<
|
||||
|
@ -1964,7 +1959,7 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
|
|||
// Issue a diagnostic if the name of the file on disk has a different case
|
||||
// than the one we're about to open.
|
||||
const bool CheckIncludePathPortability =
|
||||
File && !File->tryGetRealPathName().empty();
|
||||
!IsMapped && File && !File->tryGetRealPathName().empty();
|
||||
|
||||
if (CheckIncludePathPortability) {
|
||||
StringRef Name = LangOpts.MSVCCompat ? NormalizedPath.str() : Filename;
|
||||
|
|
|
@ -1422,7 +1422,7 @@ static bool EvaluateHasIncludeCommon(Token &Tok,
|
|||
const DirectoryLookup *CurDir;
|
||||
const FileEntry *File =
|
||||
PP.LookupFile(FilenameLoc, Filename, isAngled, LookupFrom, LookupFromFile,
|
||||
CurDir, nullptr, nullptr, nullptr);
|
||||
CurDir, nullptr, nullptr, nullptr, nullptr);
|
||||
|
||||
// Get the result value. A result of true means the file exists.
|
||||
return File != nullptr;
|
||||
|
|
|
@ -508,7 +508,7 @@ void Preprocessor::HandlePragmaDependency(Token &DependencyTok) {
|
|||
const DirectoryLookup *CurDir;
|
||||
const FileEntry *File =
|
||||
LookupFile(FilenameTok.getLocation(), Filename, isAngled, nullptr,
|
||||
nullptr, CurDir, nullptr, nullptr, nullptr);
|
||||
nullptr, CurDir, nullptr, nullptr, nullptr, nullptr);
|
||||
if (!File) {
|
||||
if (!SuppressIncludeNotFoundError)
|
||||
Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,16 @@
|
|||
// RUN: %clang_cc1 -Eonly \
|
||||
// RUN: -I%S/Inputs/nonportable-hmaps/foo.hmap \
|
||||
// RUN: -I%S/Inputs/nonportable-hmaps \
|
||||
// RUN: %s -verify
|
||||
//
|
||||
// foo.hmap contains: Foo/Foo.h -> headers/foo/Foo.h
|
||||
//
|
||||
// Header search of "Foo/Foo.h" follows this path:
|
||||
// 1. Look for "Foo/Foo.h".
|
||||
// 2. Find "Foo/Foo.h" in "nonportable-hmaps/foo.hmap".
|
||||
// 3. Look for "headers/foo/Foo.h".
|
||||
// 4. Find "headers/foo/Foo.h" in "nonportable-hmaps".
|
||||
// 5. Return.
|
||||
//
|
||||
// There is nothing nonportable; -Wnonportable-include-path should not fire.
|
||||
#include "Foo/Foo.h" // expected-no-diagnostics
|
Loading…
Reference in New Issue