@@ -881,6 +881,60 @@ diagnoseFrameworkInclude(DiagnosticsEngine &Diags, SourceLocation IncludeLoc,
881881 << IncludeFilename;
882882}
883883
884+ void HeaderSearch::DiagnoseHeaderShadowing (
885+ StringRef Filename, OptionalFileEntryRef FE, bool &DiagnosedShadowing,
886+ SourceLocation IncludeLoc, ConstSearchDirIterator FromDir,
887+ ArrayRef<std::pair<OptionalFileEntryRef, DirectoryEntryRef>> Includers,
888+ bool isAngled, int IncluderLoopIndex, ConstSearchDirIterator MainLoopIt) {
889+
890+ if (Diags.isIgnored (diag::warn_header_shadowing, IncludeLoc) || isAngled ||
891+ DiagnosedShadowing)
892+ return ;
893+
894+ DiagnosedShadowing = true ;
895+
896+ // Indicates that file is first found in the includer's directory
897+ if (!MainLoopIt) {
898+ for (size_t i = IncluderLoopIndex + 1 ; i < Includers.size (); ++i) {
899+ const auto &IncluderAndDir = Includers[i];
900+ SmallString<1024 > TmpDir = IncluderAndDir.second .getName ();
901+ llvm::sys::path::append (TmpDir, Filename);
902+ if (auto File = getFileMgr ().getFileRef (TmpDir, false , false )) {
903+ if (&File->getFileEntry () == *FE)
904+ continue ;
905+ Diags.Report (IncludeLoc, diag::warn_header_shadowing)
906+ << Filename << (*FE).getDir ().getName ()
907+ << IncluderAndDir.second .getName ();
908+ return ;
909+ } else {
910+ llvm::errorToErrorCode (File.takeError ());
911+ }
912+ }
913+ }
914+
915+ // Continue searching in the regular search paths
916+ ConstSearchDirIterator It =
917+ isAngled ? angled_dir_begin () : search_dir_begin ();
918+ if (MainLoopIt) {
919+ It = std::next (MainLoopIt);
920+ } else if (FromDir) {
921+ It = FromDir;
922+ }
923+ for (; It != search_dir_end (); ++It) {
924+ SmallString<1024 > TmpPath = It->getName ();
925+ llvm::sys::path::append (TmpPath, Filename);
926+ if (auto File = getFileMgr ().getFileRef (TmpPath, false , false )) {
927+ if (&File->getFileEntry () == *FE)
928+ continue ;
929+ Diags.Report (IncludeLoc, diag::warn_header_shadowing)
930+ << Filename << (*FE).getDir ().getName () << It->getName ();
931+ return ;
932+ } else {
933+ llvm::errorToErrorCode (File.takeError ());
934+ }
935+ }
936+ }
937+
884938// / LookupFile - Given a "foo" or \<foo> reference, look up the indicated file,
885939// / return null on failure. isAngled indicates whether the file reference is
886940// / for system \#include's or not (i.e. using <> instead of ""). Includers, if
@@ -930,6 +984,7 @@ OptionalFileEntryRef HeaderSearch::LookupFile(
930984 // This is the header that MSVC's header search would have found.
931985 ModuleMap::KnownHeader MSSuggestedModule;
932986 OptionalFileEntryRef MSFE;
987+ bool DiagnosedShadowing = false ;
933988
934989 // Check to see if the file is in the #includer's directory. This cannot be
935990 // based on CurDir, because each includer could be a #include of a
@@ -963,6 +1018,9 @@ OptionalFileEntryRef HeaderSearch::LookupFile(
9631018 if (OptionalFileEntryRef FE = getFileAndSuggestModule (
9641019 TmpDir, IncludeLoc, IncluderAndDir.second , IncluderIsSystemHeader,
9651020 RequestingModule, SuggestedModule)) {
1021+ DiagnoseHeaderShadowing (Filename, FE, DiagnosedShadowing, IncludeLoc,
1022+ FromDir, Includers, isAngled,
1023+ &IncluderAndDir - Includers.begin (), nullptr );
9661024 if (!Includer) {
9671025 assert (First && " only first includer can have no file" );
9681026 return FE;
@@ -1097,6 +1155,9 @@ OptionalFileEntryRef HeaderSearch::LookupFile(
10971155 if (!File)
10981156 continue ;
10991157
1158+ DiagnoseHeaderShadowing (Filename, File, DiagnosedShadowing, IncludeLoc,
1159+ FromDir, Includers, isAngled, -1 , It);
1160+
11001161 CurDir = It;
11011162
11021163 IncludeNames[*File] = Filename;
0 commit comments