Index: include/clang/Lex/HeaderSearch.h =================================================================== --- include/clang/Lex/HeaderSearch.h +++ include/clang/Lex/HeaderSearch.h @@ -125,6 +125,10 @@ void setHeaderRole(ModuleMap::ModuleHeaderRole Role) { HeaderRole = Role; } + + SrcMgr::CharacteristicKind getDirInfo() const { + return static_cast(DirInfo); + } }; /// \brief An external source of header file information, which may supply Index: include/clang/Lex/Preprocessor.h =================================================================== --- include/clang/Lex/Preprocessor.h +++ include/clang/Lex/Preprocessor.h @@ -1271,18 +1271,37 @@ /// in ""'s. bool GetIncludeFilenameSpelling(SourceLocation Loc,StringRef &Filename); +private: + const FileEntry *lookupFileImpl(SourceLocation FilenameLoc, + StringRef Filename, + bool IsAngled, + const DirectoryLookup *FromDir, + const DirectoryLookup *&CurDir, + SmallVectorImpl *SearchPath, + SmallVectorImpl *RelativePath, + ModuleMap::KnownHeader *SuggestedModule, + bool SkipCache); + +public: /// \brief Given a "foo" or \ reference, look up the indicated file. /// /// Returns null on failure. \p isAngled indicates whether the file /// reference is for system \#include's or not (i.e. using <> instead of ""). const FileEntry *LookupFile(SourceLocation FilenameLoc, StringRef Filename, - bool isAngled, const DirectoryLookup *FromDir, + bool IsAngled, const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir, SmallVectorImpl *SearchPath, SmallVectorImpl *RelativePath, ModuleMap::KnownHeader *SuggestedModule, bool SkipCache = false); + /// \brief Lookup a file using normal rules, like \#include, but don't count + /// this as a module use. This should be used for diagnostics purposes when + /// the file is not actually included in the translation unit. + const FileEntry *lookupFileForDiagnostics(SourceLocation FilenameLoc, + StringRef Filename, + bool IsAngled); + /// \brief Get the DirectoryLookup structure used to find the current /// FileEntry, if CurLexer is non-null and if applicable. /// Index: lib/Frontend/VerifyDiagnosticConsumer.cpp =================================================================== --- lib/Frontend/VerifyDiagnosticConsumer.cpp +++ lib/Frontend/VerifyDiagnosticConsumer.cpp @@ -370,9 +370,8 @@ PH.Advance(); // Lookup file via Preprocessor, like a #include. - const DirectoryLookup *CurDir; - const FileEntry *FE = PP->LookupFile(Pos, Filename, false, NULL, CurDir, - NULL, NULL, 0); + const FileEntry *FE = + PP->lookupFileForDiagnostics(Pos, Filename, /*IsAngled=*/false); if (!FE) { Diags.Report(Pos.getLocWithOffset(PH.C-PH.Begin), diag::err_verify_missing_file) << Filename << KindStr; Index: lib/Lex/HeaderSearch.cpp =================================================================== --- lib/Lex/HeaderSearch.cpp +++ lib/Lex/HeaderSearch.cpp @@ -549,13 +549,13 @@ // a subsequent include of "baz.h" should resolve to "whatever/foo/baz.h". // This search is not done for <> headers. if (CurFileEnt && !isAngled && !NoCurDirSearch) { - SmallString<1024> TmpDir; - // Concatenate the requested file onto the directory. - // FIXME: Portability. Filename concatenation should be in sys::Path. - TmpDir += CurFileEnt->getDir()->getName(); - TmpDir.push_back('/'); - TmpDir.append(Filename.begin(), Filename.end()); - if (const FileEntry *FE = FileMgr.getFile(TmpDir.str(),/*openFile=*/true)) { + HeaderFileInfo &IncludingHFI = getFileInfo(CurFileEnt); + bool InUserSpecifiedSystemFramework = false; + DirectoryLookup DL(CurFileEnt->getDir(), IncludingHFI.getDirInfo(), + !IncludingHFI.Framework.empty()); + if (const FileEntry *FE = + DL.LookupFile(Filename, *this, SearchPath, RelativePath, + SuggestedModule, InUserSpecifiedSystemFramework)) { // Leave CurDir unset. // This file is a system header or C++ unfriendly if the old file is. // @@ -563,7 +563,7 @@ // reallocation of the underlying vector potentially making the first // reference binding dangling. HeaderFileInfo &FromHFI = getFileInfo(CurFileEnt); - unsigned DirInfo = FromHFI.DirInfo; + SrcMgr::CharacteristicKind DirInfo = FromHFI.getDirInfo(); bool IndexHeaderMapHeader = FromHFI.IndexHeaderMapHeader; StringRef Framework = FromHFI.Framework; @@ -572,15 +572,12 @@ ToHFI.IndexHeaderMapHeader = IndexHeaderMapHeader; ToHFI.Framework = Framework; - if (SearchPath != NULL) { - StringRef SearchPathRef(CurFileEnt->getDir()->getName()); - SearchPath->clear(); - SearchPath->append(SearchPathRef.begin(), SearchPathRef.end()); - } - if (RelativePath != NULL) { - RelativePath->clear(); - RelativePath->append(Filename.begin(), Filename.end()); - } + // If the directory characteristic is User but this framework was + // user-specified to be treated as a system framework, promote the + // characteristic. + if (ToHFI.DirInfo == SrcMgr::C_User && InUserSpecifiedSystemFramework) + ToHFI.DirInfo = SrcMgr::C_System; + return FE; } } Index: lib/Lex/PPDirectives.cpp =================================================================== --- lib/Lex/PPDirectives.cpp +++ lib/Lex/PPDirectives.cpp @@ -613,10 +613,10 @@ << RequestingModule->getFullModuleName() << Filename; } -const FileEntry *Preprocessor::LookupFile( +const FileEntry *Preprocessor::lookupFileImpl( SourceLocation FilenameLoc, StringRef Filename, - bool isAngled, + bool IsAngled, const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir, SmallVectorImpl *SearchPath, @@ -645,13 +645,10 @@ // Do a standard file entry lookup. CurDir = CurDirLookup; const FileEntry *FE = HeaderInfo.LookupFile( - Filename, isAngled, FromDir, CurDir, CurFileEnt, + Filename, IsAngled, FromDir, CurDir, CurFileEnt, SearchPath, RelativePath, SuggestedModule, SkipCache); - if (FE) { - if (SuggestedModule) - verifyModuleInclude(FilenameLoc, Filename, FE); + if (FE) return FE; - } // Otherwise, see if this is a subframework header. If so, this is relative // to one of the headers on the #include stack. Walk the list of the current @@ -680,6 +677,31 @@ return 0; } +const FileEntry *Preprocessor::LookupFile( + SourceLocation FilenameLoc, + StringRef Filename, + bool IsAngled, + const DirectoryLookup *FromDir, + const DirectoryLookup *&CurDir, + SmallVectorImpl *SearchPath, + SmallVectorImpl *RelativePath, + ModuleMap::KnownHeader *SuggestedModule, + bool SkipCache) { + const FileEntry *FE = + lookupFileImpl(FilenameLoc, Filename, IsAngled, FromDir, CurDir, + SearchPath, RelativePath, SuggestedModule, SkipCache); + if (FE && SuggestedModule) + verifyModuleInclude(FilenameLoc, Filename, FE); + return FE; +} + +const FileEntry *Preprocessor::lookupFileForDiagnostics( + SourceLocation FilenameLoc, StringRef Filename, bool IsAngled) { + const DirectoryLookup *CurDir; + return lookupFileImpl(FilenameLoc, Filename, IsAngled, NULL, CurDir, + NULL, NULL, NULL, false); +} + //===----------------------------------------------------------------------===// // Preprocessor Directive Handling. Index: test/Modules/Inputs/declare-use/h.h =================================================================== --- test/Modules/Inputs/declare-use/h.h +++ test/Modules/Inputs/declare-use/h.h @@ -1,7 +1,7 @@ #ifndef H_H #define H_H #include "c.h" -#include "d.h" // expected-error {{does not depend on a module exporting}} +#include "d.h" // expected-error {{module XH does not depend on a module exporting 'd.h'}} #include "h1.h" const int h1 = aux_h*c*7*d; #endif Index: test/Modules/Inputs/declare-use/module.map =================================================================== --- test/Modules/Inputs/declare-use/module.map +++ test/Modules/Inputs/declare-use/module.map @@ -9,11 +9,13 @@ module XC { header "c.h" use XA + use XB } module XD { header "d.h" use XA + use XB } module XE { Index: test/Modules/declare-use2.cpp =================================================================== --- test/Modules/declare-use2.cpp +++ test/Modules/declare-use2.cpp @@ -3,5 +3,5 @@ #include "h.h" #include "e.h" -#include "f.h" // expected-error {{does not depend on a module exporting}} +#include "f.h" // expected-error {{module XH does not depend on a module exporting 'f.h'}} const int h2 = h1+e+f; Index: test/Modules/submodules.cpp =================================================================== --- test/Modules/submodules.cpp +++ test/Modules/submodules.cpp @@ -31,6 +31,6 @@ extern MyTypeA import_self_test_a; // expected-error {{must be imported from module 'import_self.a'}} // expected-note@import-self-a.h:1 {{here}} extern MyTypeC import_self_test_c; -// FIXME: This should be valid; import_self.b re-exports import_self.d. -extern MyTypeD import_self_test_d; // expected-error {{must be imported from module 'import_self.d'}} -// expected-note@import-self-d.h:1 {{here}} + +// import_self.b re-exports import_self.d. +extern MyTypeD import_self_test_d;