Index: include/clang/Lex/HeaderSearch.h =================================================================== --- include/clang/Lex/HeaderSearch.h +++ include/clang/Lex/HeaderSearch.h @@ -384,14 +384,12 @@ /// \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. - const FileEntry *LookupFile(StringRef Filename, SourceLocation IncludeLoc, - bool isAngled, const DirectoryLookup *FromDir, - const DirectoryLookup *&CurDir, - ArrayRef Includers, - SmallVectorImpl *SearchPath, - SmallVectorImpl *RelativePath, - ModuleMap::KnownHeader *SuggestedModule, - bool SkipCache = false); + const FileEntry *LookupFile( + StringRef Filename, SourceLocation IncludeLoc, bool isAngled, + const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir, + ArrayRef> Includers, + SmallVectorImpl *SearchPath, SmallVectorImpl *RelativePath, + ModuleMap::KnownHeader *SuggestedModule, bool SkipCache = false); /// \brief Look up a subframework for the specified \#include file. /// Index: lib/Frontend/InitPreprocessor.cpp =================================================================== --- lib/Frontend/InitPreprocessor.cpp +++ lib/Frontend/InitPreprocessor.cpp @@ -65,17 +65,12 @@ /// AddImplicitInclude - Add an implicit \#include of the specified file to the /// predefines buffer. -static void AddImplicitInclude(MacroBuilder &Builder, StringRef File, - FileManager &FileMgr) { - Builder.append(Twine("#include \"") + - HeaderSearch::NormalizeDashIncludePath(File, FileMgr) + "\""); +static void AddImplicitInclude(MacroBuilder &Builder, StringRef File) { + Builder.append(Twine("#include \"") + File + "\""); } -static void AddImplicitIncludeMacros(MacroBuilder &Builder, - StringRef File, - FileManager &FileMgr) { - Builder.append(Twine("#__include_macros \"") + - HeaderSearch::NormalizeDashIncludePath(File, FileMgr) + "\""); +static void AddImplicitIncludeMacros(MacroBuilder &Builder, StringRef File) { + Builder.append(Twine("#__include_macros \"") + File + "\""); // Marker token to stop the __include_macros fetch loop. Builder.append("##"); // ##? } @@ -94,7 +89,7 @@ return; } - AddImplicitInclude(Builder, OriginalFile, PP.getFileManager()); + AddImplicitInclude(Builder, OriginalFile); } /// \brief Add an implicit \#include using the original file used to generate @@ -107,7 +102,7 @@ if (OriginalFile.empty()) return; - AddImplicitInclude(Builder, OriginalFile, PP.getFileManager()); + AddImplicitInclude(Builder, OriginalFile); } /// PickFP - This is used to pick a value based on the FP semantics of the @@ -925,8 +920,7 @@ // If -imacros are specified, include them now. These are processed before // any -include directives. for (unsigned i = 0, e = InitOpts.MacroIncludes.size(); i != e; ++i) - AddImplicitIncludeMacros(Builder, InitOpts.MacroIncludes[i], - PP.getFileManager()); + AddImplicitIncludeMacros(Builder, InitOpts.MacroIncludes[i]); // Process -include-pch/-include-pth directives. if (!InitOpts.ImplicitPCHInclude.empty()) @@ -937,7 +931,7 @@ // Process -include directives. for (unsigned i = 0, e = InitOpts.Includes.size(); i != e; ++i) { const std::string &Path = InitOpts.Includes[i]; - AddImplicitInclude(Builder, Path, PP.getFileManager()); + AddImplicitInclude(Builder, Path); } // Exit the command line and go back to (2 is LC_LEAVE). Index: lib/Frontend/Rewrite/InclusionRewriter.cpp =================================================================== --- lib/Frontend/Rewrite/InclusionRewriter.cpp +++ lib/Frontend/Rewrite/InclusionRewriter.cpp @@ -333,10 +333,13 @@ // FIXME: Subframeworks aren't handled here. Do we care? bool isAngled = PP.GetIncludeFilenameSpelling(Tok.getLocation(), Filename); const DirectoryLookup *CurDir; + const FileEntry *FileEnt = PP.getSourceManager().getFileEntryForID(FileId); + SmallVector, 1> + Includers; + Includers.push_back(std::make_pair(FileEnt, FileEnt->getDir())); const FileEntry *File = PP.getHeaderSearchInfo().LookupFile( - Filename, SourceLocation(), isAngled, nullptr, CurDir, - PP.getSourceManager().getFileEntryForID(FileId), nullptr, nullptr, - nullptr, false); + Filename, SourceLocation(), isAngled, nullptr, CurDir, Includers, nullptr, + nullptr, nullptr, false); FileExists = File != nullptr; return true; Index: lib/Lex/HeaderSearch.cpp =================================================================== --- lib/Lex/HeaderSearch.cpp +++ lib/Lex/HeaderSearch.cpp @@ -564,8 +564,8 @@ const FileEntry *HeaderSearch::LookupFile( StringRef Filename, SourceLocation IncludeLoc, bool isAngled, const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir, - ArrayRef Includers, SmallVectorImpl *SearchPath, - SmallVectorImpl *RelativePath, + ArrayRef> Includers, + SmallVectorImpl *SearchPath, SmallVectorImpl *RelativePath, ModuleMap::KnownHeader *SuggestedModule, bool SkipCache) { if (!HSOpts->ModuleMapFiles.empty()) { // Preload all explicitly specified module map files. This enables modules @@ -616,13 +616,13 @@ // This search is not done for <> headers. if (!Includers.empty() && !isAngled && !NoCurDirSearch) { SmallString<1024> TmpDir; - for (ArrayRef::iterator I = Includers.begin(), - E = Includers.end(); - I != E; ++I) { - const FileEntry *Includer = *I; + bool First = true; + for (const auto &IncluderAndDir : Includers) { + const FileEntry *Includer = IncluderAndDir.first; + // Concatenate the requested file onto the directory. // FIXME: Portability. Filename concatenation should be in sys::Path. - TmpDir = Includer->getDir()->getName(); + TmpDir = IncluderAndDir.second->getName(); TmpDir.push_back('/'); TmpDir.append(Filename.begin(), Filename.end()); @@ -631,10 +631,9 @@ // a container that could be reallocated across this call. bool IncluderIsSystemHeader = getFileInfo(Includer).DirInfo != SrcMgr::C_User; - if (const FileEntry *FE = - getFileAndSuggestModule(*this, TmpDir.str(), Includer->getDir(), - IncluderIsSystemHeader, - SuggestedModule)) { + if (const FileEntry *FE = getFileAndSuggestModule( + *this, TmpDir.str(), IncluderAndDir.second, + IncluderIsSystemHeader, SuggestedModule)) { // Leave CurDir unset. // This file is a system header or C++ unfriendly if the old file is. // @@ -652,7 +651,7 @@ ToHFI.Framework = Framework; if (SearchPath) { - StringRef SearchPathRef(Includer->getDir()->getName()); + StringRef SearchPathRef(IncluderAndDir.second->getName()); SearchPath->clear(); SearchPath->append(SearchPathRef.begin(), SearchPathRef.end()); } @@ -660,7 +659,7 @@ RelativePath->clear(); RelativePath->append(Filename.begin(), Filename.end()); } - if (I == Includers.begin()) + if (First) return FE; // Otherwise, we found the path via MSVC header search rules. If @@ -677,6 +676,7 @@ break; } } + First = false; } } @@ -778,7 +778,7 @@ // "Foo" is the name of the framework in which the including header was found. if (!Includers.empty() && !isAngled && Filename.find('/') == StringRef::npos) { - HeaderFileInfo &IncludingHFI = getFileInfo(Includers.front()); + HeaderFileInfo &IncludingHFI = getFileInfo(Includers.front().first); if (IncludingHFI.IndexHeaderMapHeader) { SmallString<128> ScratchFilename; ScratchFilename += IncludingHFI.Framework; @@ -937,28 +937,6 @@ return FE; } -/// \brief Helper static function to normalize a path for injection into -/// a synthetic header. -/*static*/ std::string -HeaderSearch::NormalizeDashIncludePath(StringRef File, FileManager &FileMgr) { - // Implicit include paths should be resolved relative to the current - // working directory first, and then use the regular header search - // mechanism. The proper way to handle this is to have the - // predefines buffer located at the current working directory, but - // it has no file entry. For now, workaround this by using an - // absolute path if we find the file here, and otherwise letting - // header search handle it. - SmallString<128> Path(File); - llvm::sys::fs::make_absolute(Path); - bool exists; - if (llvm::sys::fs::exists(Path.str(), exists) || !exists) - Path = File; - else if (exists) - FileMgr.getFile(File); - - return Lexer::Stringify(Path.str()); -} - //===----------------------------------------------------------------------===// // File Info Management. //===----------------------------------------------------------------------===// Index: lib/Lex/PPDirectives.cpp =================================================================== --- lib/Lex/PPDirectives.cpp +++ lib/Lex/PPDirectives.cpp @@ -541,7 +541,8 @@ bool SkipCache) { // If the header lookup mechanism may be relative to the current inclusion // stack, record the parent #includes. - SmallVector Includers; + SmallVector, 16> + Includers; if (!FromDir) { FileID FID = getCurrentFileLexer()->getFileID(); const FileEntry *FileEnt = SourceMgr.getFileEntryForID(FID); @@ -550,13 +551,15 @@ // predefines buffer. Any other file is not lexed with a normal lexer, so // it won't be scanned for preprocessor directives. If we have the // predefines buffer, resolve #include references (which come from the - // -include command line argument) as if they came from the main file, this - // affects file lookup etc. - if (!FileEnt) + // -include command line argument) from the current working directory + // instead of relative to the main file. + if (!FileEnt) { FileEnt = SourceMgr.getFileEntryForID(SourceMgr.getMainFileID()); - - if (FileEnt) - Includers.push_back(FileEnt); + if (FileEnt) + Includers.push_back(std::make_pair(FileEnt, FileMgr.getDirectory("."))); + } else { + Includers.push_back(std::make_pair(FileEnt, FileEnt->getDir())); + } // MSVC searches the current include stack from top to bottom for // headers included by quoted include directives. @@ -567,7 +570,7 @@ if (IsFileLexer(ISEntry)) if ((FileEnt = SourceMgr.getFileEntryForID( ISEntry.ThePPLexer->getFileID()))) - Includers.push_back(FileEnt); + Includers.push_back(std::make_pair(FileEnt, FileEnt->getDir())); } } } Index: lib/Serialization/ASTReader.cpp =================================================================== --- lib/Serialization/ASTReader.cpp +++ lib/Serialization/ASTReader.cpp @@ -543,8 +543,7 @@ continue; SuggestedPredefines += "#include \""; - SuggestedPredefines += - HeaderSearch::NormalizeDashIncludePath(File, FileMgr); + SuggestedPredefines += File; SuggestedPredefines += "\"\n"; } @@ -556,8 +555,7 @@ continue; SuggestedPredefines += "#__include_macros \""; - SuggestedPredefines += - HeaderSearch::NormalizeDashIncludePath(File, FileMgr); + SuggestedPredefines += File; SuggestedPredefines += "\"\n##\n"; } Index: test/Frontend/print-header-includes.c =================================================================== --- test/Frontend/print-header-includes.c +++ test/Frontend/print-header-includes.c @@ -1,3 +1,4 @@ +// RUN: cd %S // RUN: %clang_cc1 -include Inputs/test3.h -E -H -o %t.out %s 2> %t.stderr // RUN: FileCheck < %t.stderr %s