Index: clang/include/clang/Lex/HeaderSearch.h =================================================================== --- clang/include/clang/Lex/HeaderSearch.h +++ clang/include/clang/Lex/HeaderSearch.h @@ -375,13 +375,16 @@ /// \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> Includers, SmallVectorImpl *SearchPath, SmallVectorImpl *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. /// Index: clang/include/clang/Lex/Preprocessor.h =================================================================== --- clang/include/clang/Lex/Preprocessor.h +++ clang/include/clang/Lex/Preprocessor.h @@ -1686,7 +1686,7 @@ SmallVectorImpl *SearchPath, SmallVectorImpl *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. Index: clang/lib/Frontend/CompilerInstance.cpp =================================================================== --- clang/lib/Frontend/CompilerInstance.cpp +++ clang/lib/Frontend/CompilerInstance.cpp @@ -858,7 +858,8 @@ /*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(); Index: clang/lib/Frontend/Rewrite/InclusionRewriter.cpp =================================================================== --- clang/lib/Frontend/Rewrite/InclusionRewriter.cpp +++ clang/lib/Frontend/Rewrite/InclusionRewriter.cpp @@ -392,7 +392,7 @@ // 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; Index: clang/lib/Lex/HeaderSearch.cpp =================================================================== --- clang/lib/Lex/HeaderSearch.cpp +++ clang/lib/Lex/HeaderSearch.cpp @@ -624,7 +624,10 @@ ArrayRef> Includers, SmallVectorImpl *SearchPath, SmallVectorImpl *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 @@ 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 @@ if (HasBeenMapped) { CacheLookup.MappedName = copyString(Filename, LookupFileCache.getAllocator()); + if (IsMapped) + *IsMapped = true; } if (!FE) continue; @@ -839,7 +847,7 @@ 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) Index: clang/lib/Lex/PPDirectives.cpp =================================================================== --- clang/lib/Lex/PPDirectives.cpp +++ clang/lib/Lex/PPDirectives.cpp @@ -752,16 +752,11 @@ } const FileEntry *Preprocessor::LookupFile( - SourceLocation FilenameLoc, - StringRef Filename, - bool isAngled, - const DirectoryLookup *FromDir, - const FileEntry *FromFile, - const DirectoryLookup *&CurDir, - SmallVectorImpl *SearchPath, + SourceLocation FilenameLoc, StringRef Filename, bool isAngled, + const DirectoryLookup *FromDir, const FileEntry *FromFile, + const DirectoryLookup *&CurDir, SmallVectorImpl *SearchPath, SmallVectorImpl *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 @@ 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 @@ // 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 @@ } // Search include directories. + bool IsMapped = false; const DirectoryLookup *CurDir; SmallString<1024> SearchPath; SmallString<1024> RelativePath; @@ -1801,7 +1797,7 @@ 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 @@ FilenameLoc, LangOpts.MSVCCompat ? NormalizedPath.c_str() : Filename, isAngled, LookupFrom, LookupFromFile, CurDir, nullptr, nullptr, - &SuggestedModule, /*SkipCache*/ true); + &SuggestedModule, &IsMapped, /*SkipCache*/ true); } } } @@ -1833,8 +1829,7 @@ 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 @@ // 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; Index: clang/lib/Lex/PPMacroExpansion.cpp =================================================================== --- clang/lib/Lex/PPMacroExpansion.cpp +++ clang/lib/Lex/PPMacroExpansion.cpp @@ -1422,7 +1422,7 @@ 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; Index: clang/lib/Lex/Pragma.cpp =================================================================== --- clang/lib/Lex/Pragma.cpp +++ clang/lib/Lex/Pragma.cpp @@ -508,7 +508,7 @@ 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; Index: clang/test/Preprocessor/nonportable-include-with-hmap.c =================================================================== --- /dev/null +++ clang/test/Preprocessor/nonportable-include-with-hmap.c @@ -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